Як змусити 404 на WordPress


40

Мені потрібно змусити 404 на деяких посадах на основі умов. Мені вдалося це зробити (хоча я не знаю, чи зробив це правильно), і я отримую 404.phpшаблон для завантаження, як очікувалося.

Мій код:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    include( get_query_template( '404' ) );
    exit; # so that the normal page isn't loaded after the 404 page
  }
}

add_action( 'template_redirect', 'rr_404_my_event', 1 );

Код 2 із цього пов'язаного питання - та сама проблема:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    global $wp_query;
    $wp_query->set_404();
  }
}

add_action( 'wp', 'rr_404_my_event' );

Мій випуск:

Хоча це виглядає добре, я отримую статус, 200 OKякщо перевіряю вкладку мережі. Оскільки це статус 200, я боюся, що пошукові системи теж можуть індексувати ці сторінки.

Очікувана поведінка:

Я хочу, щоб статус 404 Not Foundбув надісланий.


Із пов’язаних питань: wordpress.stackexchange.com/questions/73738/… - ти це читав?
фуксія

Так, я все ще отримую статус 200з цим.
RRikesh

Відповіді:


50

Ви можете спробувати функцію Wordpress, status_header()щоб додати HTTP/1.1 404 Not Foundзаголовок;

Таким прикладом вашого Code 2 буде:

function rr_404_my_event() {
  global $post;
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
    global $wp_query;
    $wp_query->set_404();
    status_header(404);
  }
}
add_action( 'wp', 'rr_404_my_event' );

Ця функція використовується, наприклад, у цій частині:

function handle_404() {
    ...cut...
    // Guess it's time to 404.
    $wp_query->set_404();
    status_header( 404 );
    nocache_headers();
    ...cut...
}

з wpкласу в /wp-includes/class-wp.php.

Тому спробуйте використовувати цей модифікований приклад Code 2 на додаток до вашого template_includeкоду.


Розроблений Code 2вами фрагмент працює чудово. Те, set_header()чого не вистачало.
Рікеш

@birgire, яку ви посилаєтесь set_header()додати, HTTP/1.1 404 Not Foundале використовували status_header()у своєму коді?
henrywright

@henrywright це схоже на друкарську помилку, я оновив відповідь, дякую ;-)
birgire

15

Цей код працював для мене:

добавлення ('wp', 'force_404');
функція force_404 () {
    глобальний $ wp_query; // $ повідомлення (якщо потрібно)
    if (is_page ()) {// ваш стан
        status_header (404);
        nocache_headers ();
        включити (get_query_template ('404'));
        die ();
    }
}

Зручно. Я перевіряю власні параметри запиту, тому не використовую дії, але це дуже корисний метод у моєму класі плагінів.
Джон Рейд

2
Додайте наступне, щоб виправити заголовок сторінки:global $wp_query; $wp_query->is_404 = true;
developerbmw

2

Я б не рекомендував форсувати 404.

Якщо ви переживаєте за пошукові системи, чому б просто не зробити мета "no-index, no-follow" на цих сторінках і заблокувати її robots.txt?

Це може бути кращим способом заблокувати перегляд вмісту

add_filter( 'template_include', 'nifty_block_content', 99 );

function nifty_block_content( $template ) {
  if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
        $template = locate_template( array( 'nifty-block-content.php' ) );
     }
    return $template;
}

Можливо, ви також можете використовувати цей метод для завантаження, 404.phpале я вважаю, що використання шаблону сторінки може бути кращим варіантом.

джерело


Дякую за посилання, я перейду до використання locate_template()замість цього. Я думаю, що robots.txt.це не гарантований спосіб захисту від індексації. Деякі пошукові системи все ж можуть забрати сторінку. Я хочу, щоб сторінка виглядала як звичайна 404 сторінка. Також повідомлення будуть динамічно додаватися, редагування robots.txtфайлу додасть більше проблем.
Рікеш

1

Моє рішення:

add_action( 'wp', 'my_404' );
function my_404() 
{
    if ( is_404() ) 
    {
        header("Status: 404 Not Found");
        $GLOBALS['wp_query']->set_404();
        status_header(404);
        nocache_headers();
        //var_dump(getallheaders()); var_dump(headers_list()); die();
    }
}

1
Перенаправлення на помилки жахливо для вашого рейтингу сторінок. Просто покажіть шаблон у тому самому місці, де і поганий запит. Що станеться, коли ви це зробите, ви спочатку встановите 404, а потім переадресація змінює його на 301 або 302, яке перенаправляє на сторінку, яка повертає 200. Потім пошукові системи індексуються як дійсна сторінка, яка явно те, що ОП сказав, що не хоче.
мопсид

0

Коди статусу надсилаються в заголовки HTTP-запитів. Ваша поточна функція підключена до гачка, який буде називатися занадто пізно.

Вам слід спробувати підключити свою функцію rr_404_my_event()до дії send_headers.

Я не впевнений, що в цей момент часу навіть можна перевірити ідентифікатор допису, але дайте цьому:

add_action( 'send_headers', 'rr_404_my_event' );
function rr_404_my_event() {
    global $post;
    if ( is_singular( 'event' ) && !rr_event_should_be_available( $post->ID ) ) {
        include( get_query_template( '404' ) );
        header('HTTP/1.0 404 Not Found');
        exit; 
    }
}

Я виправив деякі ваші синтаксичні помилки з ваших кодів. Я навіть не отримую свій шаблон 404 для завантаження.
RRikesh

Можливо, у вашому випадку 404.phpви можете завантажити інше header.php, наприклад, <?php get_header('404'); ?>завантажити header-404.php. У цьому заголовку ви додасте header('HTTP/1.0 404 Not Found');в <head>розділі.
Marc Dingena

0

Я хотів поділитися тим, як я використовував марковане рішення

function fail_safe_for_authors() {
    if ((is_user_logged_in()) && (is_author()) && ($_COOKIE["user_role"] !== "administrator")) {
            global $wp_query;
            $wp_query->set_404();
            status_header(404);
        }
}
add_action("wp", "fail_safe_for_authors");

Я зробив це, щоб відокремити всі типи користувачів від адміністратора , в цьому проекті лише адміністратор може бачити author.phpсторінку.

Я сподіваюся, що це могло б допомогти комусь іншому.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.