Выборочный обновление настройки WordPress Customizer: работает только при первом изменении настройки

Вопрос или проблема

Я создал новый контрол (флажок) в WP Customizer. Он должен работать следующим образом: соответствующий раздел должен отображать последний опубликованный пост, когда флажок установлен (true), или пользовательское фоновое изображение (и некоторый контент), когда флажок не установлен (false).

Все работает нормально при первом изменении настроек. Допустим, флажок не установлен при загрузке страницы — раздел будет отображать пользовательское фоновое изображение. Если я установлю флажок, раздел обновляется, и показывается последний пост. На этом этапе все в порядке.

Но если я сниму отметку с флажка (как второе действие с тем же контролем), ничего не происходит. Все еще ничего не происходит при последующих установках/снятиях отметки.

У меня нет никакого JS, связанного с этим контролем (я также удалил весь пользовательский JS, и проблема сохраняется).

customizer.php

$wp_customize->add_setting( 'latest_post', 
                            array(
                                'default'    => "", 
                                'type'       => 'theme_mod',
                                'capability' => 'edit_theme_options',
                                'transport'   => 'postMessage',
                            ) 
                        );
$wp_customize->add_control('latest_post', 
                            array(
                                'label'    => __( 'Содержимое заголовка', 'mytheme' ),
                                'section'  => 'header_section',
                                'settings' => 'latest_post',
                                'type'     => 'checkbox'
                            )
                        );      
$wp_customize->selective_refresh->add_partial( 'latest_post', array(
                            'selector'        => '.header-section',
                            'render_callback' => 'header_markup'
                        ) );



function header_markup(){
  $latest_post = get_theme_mod('latest_post');

  switch($latest_post):
     case true:
        return "последний пост";
     case false:
        return "пользовательский медиаконтент";
     default:
        return "пользовательский медиаконтент";
  endswitch;

}

html

<div class="header-section">
   <php echo header_markup(); ?>
</div>

Проверьте фактическое значение, возвращаемое из флажка, с помощью var_dump(). Похоже, что оно не соответствует true или false, а всегда переходит к значению по умолчанию. Даже ваше значение по умолчанию “” не является ни true, ни false.

Я считаю, что проблема в том, что ваша настройка сохраняется как строка, а не как логическое значение. Вам необходимо указать sanitize_callback при регистрации настройки, чтобы гарантировать, что она сохраняется именно так.

Я считаю, что это должно помочь:

$wp_customize->add_setting( 'latest_post',
    array(
        'default'           => false,
        'type'              => 'theme_mod',
        'capability'        => 'edit_theme_options',
        'transport'         => 'postMessage',
        'sanitize_callback' => 'wp_validate_boolean', // 👈
    )
);

Это происходит потому, что селекторы в методе add_partial и файле предварительного просмотра js не совпадают!

введите описание изображения здесь

введите описание изображения здесь

Добавьте это в массив selective_refresh:

'container_inclusive' => true,

Это помогло мне.

Пост был давно.. но никогда не знаешь, столкнутся ли другие люди с той же проблемой.

.

Ответ или решение

Проблема, с которой вы столкнулись при использовании функции "Selective Refresh" в WordPress Customizer, связанная с тем, что изменения контроллера (чекбокса) работают только при первом изменении, может быть обусловлена несколькими причинами. Давайте разберем это более подробно.

1. Проверка значений настроек

Судя по вашему описанию, проблемы возникают при повторном изменении состояния чекбокса. Вы упомянули, что результаты проверки значений не соответствуют ожидаемым true или false. Возможная причина заключается в том, что значение, сохраняемое в настройках, не является логическим, а представляется в виде строки. Это важно для корректного функционирования вашего кода.

Для правильного сохранения значения следует использовать параметр sanitize_callback, который позволяет обеспечить корректность сохранения (например, сохранить значение как логическое).

$wp_customize->add_setting('latest_post', 
    array(
        'default'           => false,
        'type'              => 'theme_mod',
        'capability'        => 'edit_theme_options',
        'transport'         => 'postMessage',
        'sanitize_callback' => 'wp_validate_boolean', // Корректная обработка значений
    )
);

2. Процесс рендеринга секции

В функции header_markup() ваши проверки значения, основанные на switch, не могут успешно выполняться, если значение не является строгим соответствием. Используя var_dump(), вы можете убедиться, что ваше значение действительно является true или false и не является строкой "1" или "0".

Перепишите вашу функцию, чтобы использовать строгое сравнение:

function header_markup(){
    $latest_post = get_theme_mod('latest_post');

    if ($latest_post) { // Явное преобразование к логическому типу
        return "latest post";
    } else {
        return "custom media";
    }
}

3. Убедитесь в корректности селекторов

Следующим шагом является проверка того, что селектор в методе add_partial совпадает с селектором в вашем HTML. Если селектор не совпадает, сегмент страницы не будет правильно обновлен. Убедитесь, что вы используете правильный селектор в add_partial().

Также стоит добавить container_inclusive в массив настройки selective_refresh, чтобы обеспечить, что обновления будут включать не только непосредственно обновляемый элемент, но и его контейнер.

$wp_customize->selective_refresh->add_partial('latest_post', array(
    'selector' => '.header-section',
    'render_callback' => 'header_markup',
    'container_inclusive' => true,
));

4. Корректная работа JavaScript

Вы не добавили JavaScript для контроля этого чекбокса. Обратите внимание, что если вы планируете использовать postMessage для асинхронного обновления, необходимо также включать соответствующий JavaScript, обеспечивающий связь между изменением настроек и обновлением интерфейса.

Заключение

Проблема с тем, что изменения работают только при первом изменении, вероятно, связана с сохранением значения как строки вместо логического типа, а также возможным несоответствием селекторов в вашем коде. Исправление этих моментов и добавление необходимого JavaScript должно помочь решить вашу проблему.

Если у вас остаются вопросы или требуется дополнительная помощь, пожалуйста, не стесняйтесь обращаться.

Оцените материал
Добавить комментарий

Капча загружается...