pre_handle_404
Дозволяє встановити запиту довільні заголовки header після того, як був зроблений основний запит.
Під час хука можна перевірити основний запит, який знаходиться в глобальній змінній $wp_query . І якщо треба, відправити на 404 сторінку, коли за умовчанням це не 404 сторінки. Або навпаки не відправляти на 404 сторінку, коли за умовчанням має бути 404 сторінка.
Якщо фільтр поверне будь що крім false, то всі перевірки, які йдуть після цього хука будуть перервані.
Що перевіряється після цього хука?
- Нічого, якщо is_404() вже спрацював.
- Якщо є записи в $wp_query->posts , але це запит пагінації окремого запису ( <!–nextpage–> ) і на вказаній сторінці пагінації вже немає контенту. Тоді виведе 404 сторінку.
- Якщо це сторінка автора, який не має записів, то не виводити 404 сторінку.
- Не виводити 404 для запиту архіву, що визначився.
- Не виводити 404, якщо спрацював хоч один тег:
is_home() || is_search() || is_feed()
Використання
add_filter( 'pre_handle_404', 'wp_kama_pre_handle_404_filter', 10, 2); /** * Function for `pre_handle_404` filter-hook. * * @param bool $preempt Whether to short-circuit default header status handling. * @param WP_Query $wp_query WordPress Query object. * * @return bool */ function wp_kama_pre_handle_404_filter( $preempt, $wp_query ){ // Filter... return $preempt; }
-
$preempt
(логічний) -
Якщо повернути будь-що крім false, то робота методу
WP::handle_404() буде перервана.
Типово: false -
$wp_query
(об’єкт) Глобальний об’єкт $wp_query .
Його також можна отримати в оброблюваної функції, вказавши на початку Global $wp_query;
Приклади
#1 Сторінка 404 для архіву автора
Припустимо, нам не потрібна сторінка архіву автора. Це може бути потрібне, коли на сайті всього 1 автор публікує статті. І якщо вказати URL /author/логін , ми потрапляємо на сторінку записів цього автора і одночасно може зрозуміти який логін використовується у автора. Для захисту від підбору паролів краще, щоб не можна було визначити логін.
Цей приклад показує, як приховати сторінку архіву автора. Приклад розбирався у питанні .
// Ставимо 404 статус add_filter( 'pre_handle_404', 'remove_author_pages_page'); function remove_author_pages_page( $false ) { if ( is_author() ) { global $wp_query; $wp_query->set_404(); status_header(404); nocache_headers(); return 'stop'; // для обриву хука } return $ false; } // видаляємо посилання add_filter( 'author_link', 'remove_author_pages_link' ); function remove_author_pages_link( $content ) { return home_url(); }
#2 Встановимо 404 сторінку для запису довільно типу
Ми маємо нестандартний URL типу запису realty , в якому присутні таксономії. Але щоб отримати сторінку запису, достатньо знати її ярлик. Нехай URL виглядає так: /realty/таксономія_type_deal/ярлик_запису . Тепер, якщо вказати в імені таксономії (терміну) будь-яке значення, сторінка запису працюватиме. А нам потрібно, щоб працювало лише одне посилання, з правильною назвою таксономії. А якщо назва неправильна, то потрібно віддавати 404 сторінки.
## 404 сторінка якщо в URL вказані неправильні назви таксономій. ## За фактом, WP потім 301 редиректит на правильний URL... add_filter( 'pre_handle_404', 'realty_404_test', 10, 2); function realty_404_test( $false, $wp_query ){ $ set_404 = false; // окремий запис оголошення if( is_singular('realty') ){ $post = get_queried_object(); $term_name = get_query_var('type_deal'); if( $term_name && ! has_term( $term_name, 'type_deal', $post ) ){ $ set_404 = 1; } } if( $set_404 ){ $wp_query->set_404(); status_header(404); nocache_headers(); return 'stop'; // обриваємо такі перевірки } return $ false; // нічого не робить... }
#3 404 для сторінок в URL яких потрапила пропуск
Якщо в URL постійної станиці потрапить пробіл, WordPress все одно покаже таку сторінку, хоча повинен би показати 404 сторінку. Тобто. така сторінка з пробілом все одно дає відповідь 200, а це дублювання контенту. Наприклад, реальний URL: /sample-page/ , а контенті його вказали як /sample- page/ , що рівносильно в результаті /sample-%20page/ .
add_filter( 'pre_handle_404', function ( $false, $wp_query ) { // Саме з 'query' елемента треба брати! $pagename = isset($wp_query->query['pagename']) ? $wp_query->query['pagename'] : ''; // якщо ярлик сторінки містить пробіл... if( strpos( $pagename, '%20' ) !== false ) { $wp_query->set_404(); status_header(404); nocache_headers(); return 'stop'; } return $ false; // нічого не робить... }, 10, 2);
#4 404 для сторінок в URL яких нуль
// Варіант із записами add_filter( 'pre_handle_404', 'fix_fake_page'); function fix_fake_page( $false ) { global $wp_query; if ( is_singular() && isset( $wp_query->query['page'] ) && $wp_query->query['page'] === '0' ) { $wp_query->set_404(); status_header(404); nocache_headers(); return 'stop'; } return $ false; } // Варіант із Рубриками add_filter( 'pre_handle_404', 'fix_fake_category_page'); function fix_fake_category_page( $false ) { global $wp_query; if ( is_archive() && get_query_var('category_name') === '0' ) { // if ( is_archive() && ! term_exists( get_query_var( 'category_name' ) ) ) ) { $wp_query->set_404(); status_header(404); nocache_headers(); return 'stop'; } return $ false; }
#5 404 для сторінок пагінації постів
Контент постів можна ділити тегом <!–nextpage–> , тоді кожна частина тексту буде доступна під своєю адресою.
Наприклад, додамо за контентом 2 таких тега, тим самим розділимо його на 3 частини, які будуть доступні за такими адресами:
- 1 частина –
https://site.com/test-post/
- 2 частина –
https://site.com/test-post/2/
- 3 частина –
https://site.com/test-post/3/
Якщо перейти на адресу https://site.com/test-post/1/
, то перенаправить на https://site.com/test-post/ , тут все логічно. Але якщо перейти на https://site.com/test-post/4/ або іншу неіснуючу частину контенту – відобразиться все як завжди, але тексту не буде (частини 4 немає). Тобто сторінка є, а контенту немає. У таких випадках має бути помилка 404, але WP віддає відповідь 200, що може погано сказати сео. Виправимо цю поведінку.
Цей недолік є не на всіх сайтах!
За замовчуванням WP перенаправляє на основну УРЛ з неіснуючої сторінки пагінації записів (постів).
Найімовірніше це пов’язано з відключенням функції redirect_canonical() :
remove_action( 'template_redirect', 'redirect_canonical');
// Варіант 1. Скасуємо пагінацію окремих сторінок // (Тенденція, що їх ніхто і не використовує) add_filter( 'pre_handle_404', 'remove_single_post_pagination', 10, 2); function remove_single_post_pagination( $false, $wp_query ) { if ( is_singular() && get_query_var( 'page' ) ) { $wp_query->set_404(); status_header(404); nocache_headers(); return 'stop'; } return $ false; }
список змін
З версії 4.5.0 | Введено. |
Де викликається хук
if ( false !== apply_filters( 'pre_handle_404', false, $wp_query ) ) {