Come forzare un 404 su WordPress


40

Ho bisogno di forzare un 404 su alcuni post in base alle condizioni. Sono riuscito a farlo (anche se non so se l'ho fatto nel modo giusto) e sto facendo 404.phpcaricare il mio modello come previsto.

Il mio codice:

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

Codice 2 da questa domanda correlata - stesso 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' );

Il mio problema:

Anche se sembra buono, ottengo uno stato 200 OKse controllo la scheda di rete. Dal momento che è uno stato 200, temo che anche i motori di ricerca possano indicizzare quelle pagine.

Comportamento previsto:

Voglio 404 Not Foundche venga inviato uno stato .


Dalle domande correlate: wordpress.stackexchange.com/questions/73738/… - l'hai letto?
fuxia

Sì, ottengo ancora uno stato 200con quello.
RRikesh,

Risposte:


51

Puoi provare la funzione Wordpress status_header()per aggiungere l' HTTP/1.1 404 Not Foundintestazione;

Quindi il tuo esempio di codice 2 sarebbe:

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

Questa funzione è ad esempio utilizzata in questa parte:

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

dalla wpclasse in /wp-includes/class-wp.php.

Quindi prova a utilizzare questo esempio di codice 2 modificato oltre al tuo template_includecodice.


Lo Code 2snippet che hai pubblicato funziona perfettamente. L' set_header()era quello che mancava.
RRikesh,

@birgire ti riferisci per set_header()aggiungere HTTP/1.1 404 Not Foundma hai usato status_header()nel tuo codice?
henrywright,

@henrywright sembra un errore di battitura lì, ho aggiornato la risposta, grazie ;-)
birgire

15

Questo codice ha funzionato per me:

add_action ('wp', 'force_404');
funzione force_404 () {
    $ wp_query globale; // $ posts (se richiesto)
    if (is_page ()) {// la tua condizione
        status_header (404);
        nocache_headers ();
        include (get_query_template ('404'));
        morire();
    }
}

Maneggevole. Sto verificando i parametri di query personalizzati, quindi non sto usando l'azione, ma è un metodo molto utile nella mia classe di plugin.
John Reid,

2
Aggiungi quanto segue per correggere il titolo della pagina:global $wp_query; $wp_query->is_404 = true;
developerbmw

2

Non consiglierei di forzare un 404.

Se sei preoccupato per i motori di ricerca, perché non fare semplicemente una meta "no-index, no-follow" su quelle pagine e bloccarla con robots.txt?

Questo potrebbe essere un modo migliore per bloccare la visualizzazione del contenuto

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

Probabilmente potresti anche usare questo metodo per caricare, 404.phpma penso che l'uso di un modello di pagina potrebbe essere un'opzione migliore.

fonte


Grazie mille per il link, passerò locate_template()invece all'utilizzo . Penso che robots.txt.non sia un modo garantito per proteggere dall'indicizzazione. Alcuni motori di ricerca potrebbero ancora raccogliere la pagina. Voglio che la pagina appaia come una normale pagina 404. Inoltre, i post verranno aggiunti in modo dinamico, la modifica del robots.txtfile aggiungerà ulteriori problemi.
RRikesh,

1

La mia soluzione:

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
Il reindirizzamento sugli errori è terribile per il posizionamento della tua pagina. Mostra solo un modello nella stessa posizione della richiesta errata. Cosa succede quando lo fai è inizialmente impostare un 404, quindi il reindirizzamento lo modifica in un 301 o 302, che quindi reindirizza a una pagina che restituisce un 200. Che viene quindi indicizzato dai motori di ricerca come una pagina valida, che è esplicitamente ciò che OP ha detto che non voleva.
mopsyd,

0

I codici di stato vengono inviati nelle intestazioni delle richieste HTTP. La tua attuale funzione è collegata a un hook che verrà chiamato troppo tardi.

Dovresti provare a collegare la tua funzione rr_404_my_event()all'azione send_headers.

Non sono sicuro che a quel punto sia persino possibile controllare l'ID postale, ma provalo:

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

Ho corretto alcuni errori di sintassi dai tuoi codici. Non riesco nemmeno a caricare il mio modello 404 con quello.
RRikesh

Forse, nel tuo 404.phppotresti caricarne un altro header.php, ad es. <?php get_header('404'); ?>Per caricare header-404.php. In quell'intestazione, aggiungeresti header('HTTP/1.0 404 Not Found');nella <head>sezione.
Marc Dingena,

0

Volevo condividere il modo in cui ho usato la soluzione contrassegnata

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

Ho fatto questo per separare tutti i tipi di utente dal dell'amministratore , in questo progetto, solo l'amministratore può vedere la author.phppagina.

Spero possa aiutare qualcun altro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.