Как заставить 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/… - Вы это читали?
fuxia

Да, я все еще получаю статус 200с этим.
RRikesh

Ответы:


51

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

Таким образом, ваш пример кода 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()было то, чего не хватало.
RRikesh

@birgire вы ссылаетесь, чтобы set_header()добавить, HTTP/1.1 404 Not Foundно использовали status_header()в своем коде?
Генрирайт

@henrywright там похоже на опечатку, я обновил ответ, спасибо ;-)
birgire

15

Этот код работал для меня:

add_action ('wp', 'force_404');
function force_404 () {
    глобальный $ wp_query; // $ posts (если требуется)
    if (is_page ()) {// ваше состояние
        status_header (404);
        nocache_headers ();
        include (get_query_template ('404'));
        умереть();
    }
}

Handy. Я проверяю пользовательские параметры запроса, поэтому я не использую действие, но оно делает его очень полезным методом в моем классе плагинов.
Джон Рейд

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

2

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

Если вы беспокоитесь о поисковых системах, почему бы просто не создать мета «без индекса, без подписки» на этих страницах и заблокировать ее с помощью 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файла добавит больше проблем.
RRikesh

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>раздел.
Марк Дингена

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.