Сброс кэша страниц в WordPress обычно вешают на save_post: запись сохранили — её адрес и архивы рубрик почистили. Пока страница живёт в кэше полчаса, пропущенный случай незаметен. Когда кэш живёт неделю, каждая правка мимо этого хука — неделя устаревшего сайта.
Это третья часть цикла «WordPress на кэшируемом сайте». Здесь — где WordPress меняет то, что видно на страницах, не сохраняя запись, или сохраняя, но не там, где ждёт сброс.
1. Новая статья видна не только по своему адресу
save_post честно почистит адрес статьи и её рубрику. Но новая статья появляется ещё на главной, в общем списке блога, в блоке «похожие» у соседних статей, на странице цикла. Точечная чистка этого не знает.
У нас решение грубое и надёжное: появление статьи в публикации или уход из неё — полный сброс и обход сайта заново. Статьи выходят редко, а обход маленького сайта занимает минуты.
add_action('transition_post_status', function ($new, $old, $post) {
if ($post->post_type === 'post' && ($new === 'publish' || $old === 'publish')) {
cache_purge_all(); // главная, списки, рубрики, «похожие» — всё сразу
}
}, 10, 3);
Тот же хук ловит и отложенную публикацию, которую делает крон (если крон у вас вообще работает — вторая часть).
2. Мета меняется без сохранения записи
update_post_meta не вызывает save_post. Всё, что пишет мету в обход редактора, — обмен с 1С, импорт, API, — сброс не запустит.
Пример с этого сайта: на нём работает сервер обновлений моих плагинов. Новый выпуск приходит из CI запросом к API и записывает в мету плагина список версий. Версия видна на странице плагина, на главной и в списке плагинов — а запись при этом никто не сохраняет. Поэтому код выпуска сам ставит эти три адреса в очередь чистки:
update_post_meta($postId, '_repo_releases', $releases);
// версия видна на странице плагина, на главной и в архиве — чистим их
cache_queue_url(get_permalink($postId));
cache_queue_url(home_url('/'));
cache_queue_url(get_post_type_archive_link('plugin'));
3. Настройки сайта живут в опциях
Телефон в шапке, ссылки в подвале, коды счётчиков — это update_option, никакого save_post. А видно их на каждой странице. Поэтому изменение таких опций — полный сброс, и список опций надо вести явно:
add_filter('cache_tracked_options', function ($options) {
return array_merge($options, [
'theme_options', // контакты, тексты шапки и подвала
'theme_codes_head', // коды в <head>
'theme_tracking_scripts', // счётчики
]);
});
Случай из практики. На одном сайте контакты поддоменов хранились отдельным типом записи. Сохранение такой записи чистило только её собственный адрес, а контакты выводились в шапке и подвале каждой страницы поддомена. Поддомен неделю показывал пустую ссылку на Telegram.
4. Прямые запросы к базе
Всё, что пишет в базу мимо API WordPress, хуков не вызывает вообще: массовая замена через UPDATE wp_posts, правка в phpMyAdmin, скрипт миграции. Поэтому в наших служебных скриптах, которые меняют записи напрямую, последняя строка — сброс кэша. Сброс — часть скрипта, а не отдельный шаг «потом не забыть».
5. Меню, рубрики, виджеты
Меню и списки рубрик стоят на многих страницах сразу, поэтому их изменения у нас — полный сброс: wp_update_nav_menu, created_term, edited_term, delete_term, customize_save_after, switch_theme.
Как найти свои дыры за полчаса
- откройте типовую страницу и выпишите всё, что в ней не текст статьи: шапку, подвал, блоки «похожие», счётчики, версии, контакты;
- для каждого пункта найдите, где он хранится: запись, мета, опция, терм, другая таблица;
- для каждого места хранения найдите, каким хуком его изменение сбрасывает кэш;
- если хука нет или он чистит не те адреса — это дыра.
Четыре класса таких дыр, которые мы нашли, переведя сайты на кэш на неделю, — в 17-й части цикла про кэш страниц.
Правите в админке, а на сайте старое?
Пришлите адрес и что именно меняли — найду, какой путь изменения не сбрасывает кэш.
// загружаю комментарии…