Comment forcer un 404 sur WordPress

40

Je dois forcer un 404 sur certains postes en fonction des conditions. J'ai réussi à le faire (bien que je ne sache pas si je l'ai fait correctement) et je suis en train de 404.phptélécharger mon modèle comme prévu.

Mon code:

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

Code 2 de cette question connexe - même problème:

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

Mon problème:

Bien que cela ait l' air bien, j'obtiens un statut 200 OKsi je vérifie l'onglet Réseau. Comme il s'agit d'un statut 200, je crains que les moteurs de recherche ne puissent également indexer ces pages.

Comportement attendu:

Je veux qu'un statut 404 Not Foundsoit envoyé.

RRikesh
la source
Parmi les questions connexes: wordpress.stackexchange.com/questions/73738/… - avez-vous lu cela?
fuxia
Oui, j'ai toujours un statut 200avec ça.
RRikesh

Réponses:

51

Vous pouvez essayer la fonction Wordpress status_header() pour ajouter l'en- HTTP/1.1 404 Not Foundtête.

Ainsi, votre exemple de code 2 serait:

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

Cette fonction est par exemple utilisée dans cette partie:

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

de la wpclasse à /wp-includes/class-wp.php.

Essayez donc d'utiliser cet exemple de code 2 modifié en plus de votre template_includecode.

birgire
la source
L' Code 2extrait que vous avez posté fonctionne parfaitement. Le set_header()était ce qui manquait.
RRikesh
@birgire vous faites référence à set_header()ajouter HTTP/1.1 404 Not Foundmais avez utilisé status_header()dans votre code?
henrywright
@henrywright cela ressemble à une faute de frappe là, j'ai mis à jour la réponse, merci ;-)
birgire
15

Ce code a fonctionné pour moi:

add_action ('wp', 'force_404');
fonction force_404 () {
    global $ wp_query; // $ posts (si nécessaire)
    if (is_page ()) {// votre condition
        status_header (404);
        nocache_headers ();
        include (get_query_template ('404'));
        mourir();
    }
}
Golchha21
la source
Pratique. Je vérifie les paramètres de requête personnalisés afin de ne pas utiliser l'action, mais cela en fait une méthode très utile dans ma classe de plug-in.
John Reid
2
Ajoutez ce qui suit pour corriger le titre de la page:global $wp_query; $wp_query->is_404 = true;
developerbmw le
2

Je ne recommanderais pas de forcer un 404.

Si les moteurs de recherche vous inquiètent, pourquoi ne pas simplement faire une méta "sans index, sans suivi" sur ces pages et la bloquer avec le fichier robots.txt?

Cela peut être un meilleur moyen d'empêcher l'affichage du contenu.

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

Vous pourriez probablement aussi utiliser cette méthode pour charger, 404.phpmais j’estime que l’utilisation d’un modèle de page pourrait être une meilleure option.

la source

Brooke.
la source
Merci beaucoup pour le lien, je vais passer à utiliser à la locate_template()place. Je pense que ce robots.txt.n'est pas un moyen garanti de se protéger de l'indexation. Certains moteurs de recherche peuvent toujours prendre la page. Je veux que la page ressemble à une page 404 normale. De plus, les articles vont être ajoutés dynamiquement, la modification du robots.txtfichier ajoutera plus de problèmes.
RRikesh
1

Ma solution:

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
la source
1
La redirection sur les erreurs est terrible pour votre classement de page. Il suffit de montrer un modèle au même endroit que la mauvaise demande. Ce qui se passera quand vous ferez cela, vous aurez initialement défini un 404, puis la redirection le modifiera en un 301 ou 302, qui redirigera ensuite vers une page renvoyant un 200. Les moteurs de recherche l'indexeront ensuite comme une page valide. est explicitement ce que OP a dit qu'il ne voulait pas.
Mopsyd
0

Les codes de statut sont envoyés dans les en-têtes des requêtes HTTP. Votre fonction actuelle est accrochée à un crochet qui sera appelé trop tard.

Vous devriez essayer d’accrocher votre fonction rr_404_my_event()à l’action send_headers.

Je ne sais pas si à ce moment-là, il est même possible de vérifier l'identifiant de la publication, mais essayez ceci:

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
la source
J'ai corrigé des erreurs de syntaxe de vos codes. Je n'arrive même pas à charger mon modèle 404 avec cela.
RRikesh
Peut-être, dans votre, 404.phpvous pourriez charger un autre header.php, par exemple <?php get_header('404'); ?>pour charger header-404.php. Dans cet en-tête, vous ajouteriez header('HTTP/1.0 404 Not Found');dans la <head>section.
Marc Dingena
0

Je voulais partager la façon dont j'ai utilisé la solution marquée

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

J'ai fait cela pour séparer tous les types d'utilisateurs de l' administrateur , dans ce projet, seul l'administrateur peut voir la author.phppage.

J'espère que cela pourrait aider quelqu'un d'autre.

Gendrith
la source