Wie man ein 404 auf WordPress erzwingt


40

Ich muss auf einigen Posts eine 404 erzwingen, basierend auf den Bedingungen. Ich habe es geschafft (obwohl ich nicht weiß, ob ich es richtig gemacht habe) und ich bekomme eine 404.phpVorlage, die wie erwartet geladen wird.

Mein 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 aus dieser verwandten Frage - das gleiche Problem:

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

Mein Problem:

Obwohl es gut aussieht , erhalte ich einen Status, 200 OKwenn ich die Netzwerkregisterkarte überprüfe. Da es sich um einen Status handelt 200, befürchte ich, dass Suchmaschinen diese Seiten auch indizieren könnten.

Erwartetes Verhalten:

Ich möchte, dass ein Status 404 Not Foundgesendet wird.


Aus den verwandten Fragen: wordpress.stackexchange.com/questions/73738/… - hast du das gelesen?
Fuxia

Ja, ich bekomme immer noch einen Status 200.
RRikesh

Antworten:


50

Sie können die Wordpress-Funktion verwenden status_header(), um den HTTP/1.1 404 Not FoundHeader hinzuzufügen .

Ihr Code 2- Beispiel wäre also:

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

Diese Funktion wird zum Beispiel in diesem Teil verwendet:

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

von der wpKlasse in /wp-includes/class-wp.php.

Versuchen Sie also, dieses modifizierte Code 2- Beispiel zusätzlich zu Ihrem template_includeCode zu verwenden.


Das von Code 2Ihnen gepostete Snippet funktioniert einwandfrei. Dem set_header()fehlte was.
RRikesh

@birgire Sie beziehen sich set_header()auf hinzufügen HTTP/1.1 404 Not Found, haben aber status_header()in Ihrem Code verwendet?
Henrywright

@henrywright es sieht aus wie ein Tippfehler, ich habe die Antwort aktualisiert, danke ;-)
birgire

15

Dieser Code hat bei mir funktioniert:

add_action ('wp', 'force_404');
Funktion force_404 () {
    global $ wp_query; // $ posts (falls erforderlich)
    if (is_page ()) {// dein Zustand
        status_header (404);
        nocache_headers ();
        include (get_query_template ('404'));
        sterben();
    }
}

Praktisch. Ich suche nach benutzerdefinierten Abfrageparametern, damit ich die Aktion nicht verwende, aber sie ist eine sehr nützliche Methode in meiner Plugin-Klasse.
John Reid

2
Fügen Sie Folgendes hinzu, um den global $wp_query; $wp_query->is_404 = true;
developerbmw

2

Ich würde nicht empfehlen, einen 404 zu erzwingen.

Wenn Sie sich Sorgen um Suchmaschinen machen, warum nicht einfach ein "no-index, no-follow" -Meta auf diesen Seiten erstellen und es mit robots.txt blockieren?

Dies ist möglicherweise eine bessere Möglichkeit, die Anzeige von Inhalten zu blockieren

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

Sie könnten diese Methode wahrscheinlich auch zum Laden verwenden, 404.phpaber ich bin der Meinung, dass die Verwendung einer Seitenvorlage eine bessere Option ist.

Quelle


Vielen Dank für den Link, ich werde locate_template()stattdessen mit wechseln . Ich denke, das robots.txt.ist keine garantierte Methode zum Schutz vor Indexierung. Einige Suchmaschinen nehmen die Seite möglicherweise noch auf. Ich möchte, dass die Seite wie eine normale 404-Seite aussieht. Außerdem werden die Posts dynamisch hinzugefügt. Das Bearbeiten der robots.txtDatei wird weitere Probleme verursachen.
RRikesh

1

Meine Lösung:

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
Das Umleiten auf Fehler ist für Ihr Seitenranking schrecklich. Zeigen Sie einfach eine Vorlage am selben Ort wie die schlechte Anfrage. Wenn Sie dies tun, setzen Sie zunächst eine 404, und die Umleitung ändert diese auf 301 oder 302, die dann auf eine Seite umleiten, die eine 200 zurückgibt. Diese wird dann von den Suchmaschinen als gültige Seite indiziert ist ausdrücklich das, was OP sagte, dass er nicht wollte.
Mopsyd

0

Statuscodes werden in den Headern von HTTP-Anforderungen gesendet. Ihre aktuelle Funktion ist in einen Hook eingebunden, der zu spät aufgerufen wird.

Sie sollten versuchen, Ihre Funktion rr_404_my_event()in Aktion zu setzen send_headers.

Ich bin mir nicht sicher, ob es zu diesem Zeitpunkt überhaupt möglich ist, die Post-ID zu überprüfen, aber probieren Sie es aus:

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

Ich habe einige Syntaxfehler aus Ihren Codes korrigiert. Ich bekomme nicht einmal meine 404-Vorlage damit zu laden.
RRikesh

Vielleicht 404.phpkönntest du in deinem einen anderen laden header.php, zB <?php get_header('404'); ?>laden header-404.php. In dieser Überschrift würden Sie header('HTTP/1.0 404 Not Found');im <head>Abschnitt hinzufügen .
Marc Dingena

0

Ich wollte mitteilen, wie ich die markierte Lösung verwendet habe

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

Ich habe dies getan, um alle Benutzertypen vom Administrator zu trennen. In diesem Projekt kann nur der Administrator die author.phpSeite sehen.

Ich hoffe es konnte jemand anderem helfen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.