Como forçar um 404 no WordPress

40

Preciso forçar um 404 em algumas postagens com base nas condições. Consegui fazer isso (embora não saiba se fiz da maneira certa) e estou carregando meu 404.phpmodelo para carregar conforme o esperado.

Meu código:

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 );

Código 2 desta pergunta relacionada - mesmo problema:

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' );

Meu problema:

Embora pareça bom, recebo um status 200 OKse verificar a guia de rede. Como é um status 200, receio que os mecanismos de pesquisa também possam indexar essas páginas.

Comportamento esperado:

Quero que um status 404 Not Foundseja enviado.

RRikesh
fonte
Nas perguntas relacionadas: wordpress.stackexchange.com/questions/73738/… - você leu isso?
fuxia
Sim, eu ainda tenho um status 200com isso.
RRikesh

Respostas:

50

Você pode tentar a função Wordpress status_header()para adicionar o HTTP/1.1 404 Not Foundcabeçalho;

Portanto, seu exemplo do Code 2 seria:

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' );

Esta função é usada, por exemplo, nesta parte:

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

da wpclasse em /wp-includes/class-wp.php.

Portanto, tente usar este exemplo de código 2 modificado, além do seu template_includecódigo.

Birgire
fonte
O Code 2trecho que você postou funciona perfeitamente. A set_header()era o que estava faltando.
RRikesh
@ Birgire você se refere a set_header()adicionar, HTTP/1.1 404 Not Foundmas já usou status_header()em seu código?
Henrywright 8/08
@henrywright parece que um erro de digitação lá, eu atualizei a resposta, graças ;-)
birgire
15

Este código funcionou para mim:

add_action ('wp', 'force_404');
função force_404 () {
    global $ wp_query; // $ posts (se necessário)
    if (is_page ()) {// sua condição
        cabeçalho_do_ status (404);
        nocache_headers ();
        include (get_query_template ('404'));
        morrer();
    }
}
golchha21
fonte
Handy. Estou verificando parâmetros de consulta personalizados para não usar a ação, mas é um método muito útil na minha classe de plug-in.
John Reid
2
Adicione o seguinte para corrigir o título da página:global $wp_query; $wp_query->is_404 = true;
developerbmw
2

Eu não recomendaria forçar um 404.

Se você está preocupado com os mecanismos de pesquisa, por que não fazer uma meta "sem índice, sem seguir" nessas páginas e bloqueá-la com robots.txt?

Pode ser uma maneira melhor de impedir que o conteúdo seja visualizado

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;
}

Você provavelmente também pode usar esse método para carregar, 404.phpmas acho que usar um modelo de página pode ser uma opção melhor.

fonte

Brooke.
fonte
Muito obrigado pelo link, passarei a usar em seu locate_template()lugar. Eu acho que robots.txt.não é uma maneira garantida de se proteger da indexação. Alguns mecanismos de pesquisa ainda podem pegar a página. Eu quero que a página pareça uma página 404 normal. Além disso, as postagens serão adicionadas dinamicamente; a edição do robots.txtarquivo causará mais problemas.
RRikesh
1

Minha solução:

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();
    }
}
T.Todua
fonte
11
Redirecionar erros é terrível para o seu ranking da página. Apenas mostre um modelo no mesmo local da solicitação incorreta. O que acontecerá quando você fizer isso é definir inicialmente um 404 e, em seguida, o redirecionamento o altera para um 301 ou 302, que depois redireciona para uma página que retorna 200. Isso é indexado pelos mecanismos de pesquisa como uma página válida, que é explicitamente o que o OP disse que não queria.
Mpsyd
0

Os códigos de status são enviados nos cabeçalhos das solicitações HTTP. Sua função atual está conectada a um gancho que será chamado tarde demais.

Você deve tentar ligar sua função rr_404_my_event()à ação send_headers.

Não tenho certeza se, nesse momento, é possível verificar o ID da postagem, mas tente:

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; 
    }
}
Marc Dingena
fonte
Corrigi alguns erros de sintaxe dos seus códigos. Eu nem consigo carregar meu modelo 404 com isso.
RRikesh
Talvez 404.phpvocê possa carregar um diferente header.php, por exemplo, <?php get_header('404'); ?>para carregar header-404.php. Nesse cabeçalho, você adicionaria header('HTTP/1.0 404 Not Found');na <head>seção.
Marc Dingena
0

Eu queria compartilhar a maneira como usei a solução marcada

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");

Fiz isso para separar todos os tipos de usuários do administrador . Neste projeto, apenas o administrador pode ver a author.phppágina.

Espero que possa ajudar outra pessoa.

Gendrith
fonte