I need to force a 404 on some posts based on conditions. I managed to do it ( although I don’t know if I did it the right way) and I’m a getting my 404.php
template to load as expected.
My 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 from this related question – same 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' );
My Issue:
Although it looks good, I get a status 200 OK
if I check the network tab. Since it’s a status 200
, I am afraid that search engines might index those pages too.
Expected Behaviour:
I want a status 404 Not Found
to be sent.
You could try the WordPress function
status_header()
to add theHTTP/1.1 404 Not Found
header;So your Code 2 example would be:
This function is for example used in this part:
from the
wp
class in/wp-includes/class-wp.php
.So try using this modified Code 2 example in addition to your
template_include
code.This code worked for me:
I wouldn’t recommend forcing a 404.
If you’re worried about search engines why not just do a “no-index,no-follow” meta on those pages and block it with robots.txt?
This may be a better way to block the content from being viewed
You could probably also use this method to load
404.php
but I feel that using a page template might be a better option.source
My solution:
I wanted to share the way I used the marked solution
I did this to separate all user types from the administrator, in this project, Only the admin can see the
author.php
page.I hope it could help somebody else.
The most robust way I’ve found of achieving this is to do it in the
template_include
filter, like so:Status codes are sent in the headers of HTTP requests. Your current function is hooked into a hook that will be called too late.
You should try to hook your function
rr_404_my_event()
into actionsend_headers
.I’m not sure if at that point in time it’s even possible to check the Post ID, but give this a go: