Вопрос или проблема
Я не уверен, правда ли это, но, похоже, содержимое виджетов кэшируется. Сначала я думал, что проблема в моем коде (мне нужно скрывать/показывать раздел в пользовательском виджете в зависимости от значения сессии), но у меня такая же проблема со всеми виджетами и get_option().
Я провел этот тест.
На странице “А” я обновляю опцию:
update_option( 'custom_check', 'a' );
На странице “B” я обновляю ту же опцию с другим значением:
update_option( 'custom_check', 'b' );
Когда я перехожу со страницы “A” на “B” (или наоборот), опции корректно обновляются в базе данных. И значение правильно выводится на странице с:
echo get_option( 'custom_check' );
Но если я вывожу значение в виджете (я пробовал с разными виджетами, включая текстовый по умолчанию и виджет недавних записей), значение не обновляется. До обновления страницы.
Пример: я нахожусь на странице “A”, поэтому значение “a”. Когда я посещаю страницу “B”, значение “b” в базе данных и правильно выводится в содержимом страницы. Но виджет отображает старое значение (“a”). Когда я обновляю страницу, виджет отображает правильное значение (“b”).
Какие идеи?
[Редактировать] Я постараюсь лучше объяснить, что имею в виду.
Я использую Twenty Fourteen, не кастомную тему. В боковой панели у меня меню со страницами “А” и “B”, так что я могу посещать эти страницы одним кликом (@s_ha_dum♦ без AJAX). И текстовый виджет по умолчанию, включенный в WordPress.
В page.php
(Twenty Fourteen) у меня есть этот код вверху:
<?php
if ( is_page( 749 ) ) {
update_option( 'custom_check', 'a' );
} elseif ( is_page( 800 ) ) {
update_option( 'custom_check', 'b' );
}
echo get_option( 'custom_check' );
?>
749 и 800 — это ID страниц “А” и “B”.
Чтобы протестировать переменную в виджете, я вставил эту строку в /wp-includes/default-widgets.php
(я знаю, что это плохая практика, я просто тестирую), внутри класса WP_Widget_Text:
echo get_option( 'custom_check' );
Проблема: я нахожусь на странице “A”, “custom_check” равно “a”, и виджет отображает “a”. Когда я нажимаю на ссылку страницы “B” в меню, “custom_check” равно “b” в базе данных и правильно выводится вверху страницы. Но в текстовом виджете я по-прежнему вижу “a”. Если я обновлю страницу, виджет покажет правильное значение.
Это проблема кэша? Или, может быть, обновление опции срабатывает слишком поздно (после widget_init)?
Хорошо, похоже, что проблема не связана с кэшом. А с порядком выполнения действий. Если я обновляю значение внутри шаблона страницы (или внутри шорткода, поэтому я начал свои тесты), обновление срабатывает после рендеринга виджета.
Решение: обновить значение внутри действия. В этом примере вы можете использовать действие 'wp'
:
function test() {
if ( is_page( 749 ) ) {
update_option( 'custom_check', 'a' );
} elseif ( is_page( 800 ) ) {
update_option( 'custom_check', 'b' );
}
}
add_action( 'wp', 'test' );
Ответ или решение
Кэшируются ли виджеты WordPress?
Когда речь заходит о виджетах WordPress, важной темой является способ их обновления и возможная кэшированность содержимого. Давайте разберем эту тему более подробно, основываясь на приведенном выше примере, чтобы выяснить, что именно происходит с обновлениями опций в виджетах и как это связано с кэшированием.
Суть проблемы
В вашем случае была проделана работа по обновлению опции custom_check
на разных страницах. Когда вы переходите с одной страницы на другую, значение в базе данных изменяется корректно, но отображение этого значения в виджетах происходит несвоевременно — необходима дополнительная перезагрузка страницы, чтобы увидеть изменения. Это может вызывать недоумение и ставить под сомнение, кэшируются ли виджеты.
Природа кэширования в WordPress
В WordPress действительно существует механизм кэширования — он включает различные уровни кэширования, начиная от базы данных и заканчивая кэшированием на уровне серверов и браузеров. Однако, в данном случае причина проблемы явно не кэширование, а порядок выполнения действий.
Порядок выполнения действий
При текущем способе обновления опции с помощью update_option()
в page.php
, это происходит до того, как виджеты будут инициализированы. Виджеты рендерятся на этапе widget_init
, который происходит позже. Следовательно, любое обновление опции в коде страницы не будет отражено в виджетах, пока страница не будет обновлена.
Решение проблемы
Изменяя ваш код, чтобы использовать подходящий хук, такой как wp
, вы обеспечите обновление опции в нужное время. Вот как это можно сделать:
function test() {
if ( is_page( 749 ) ) {
update_option( 'custom_check', 'a' );
} elseif ( is_page( 800 ) ) {
update_option( 'custom_check', 'b' );
}
}
add_action( 'wp', 'test' );
Этот код гарантирует, что обновление произойдет в момент, когда контент страницы и виджеты уже инициализированы, что решает описанную вами проблему.
Заключение
Виджеты WordPress не кэшируются в классическом понимании, как это можно было бы предположить. Ваша проблема заключается в порядке выполнения кода, а не в кэшировании. Правильное использование хуков в WordPress позволяет управлять процессами обновления данных так, чтобы ваши виджеты отображали актуальную информацию. Это является важным аспектом, который нужно учитывать при разработке с использованием WordPress, чтобы избежать неожиданных проблем при работе с динамическим контентом.
Следует также помнить, что подход к кэшированию может различаться в зависимости от используемых плагинов и серверных настроек, поэтому важно всегда тестировать и проверять поведение вашего сайта.