How can I get something like this to work?

// in a plugin / theme:
// This imaginary function will make WordPress think that the 
// current request is a 404. 
// Ideally this function could be ran anywhere, but realistically it
// will probably have to be before the template_redirect hook runs.

// later...
add_action('template_redirect', function() {
    // should be "true"

Basically under certain conditions, I want to tell WordPress to show its 404 template (which I can hook into later if I want) instead of the template it's about to load (eg a page or archive).

I know I could just do a 302 redirect to a non-existent page but that's very messy. I could also send a 404 HTTP header manually, but then I can't use WP's nice 404 page (I already have things that hook into is_404() that need to get fired at the right time).

  • Perhaps I could modify the query to search for a non-existent page. – dave1010 Nov 23 '12 at 14:24
  • Can you clarify the question here? Are you trying to run code on your theme's 404 page or do you intentionally want to create a 404 error? – Steve Nov 23 '12 at 14:32
  • I want to create a 404. I'll edit the question a bit... – dave1010 Nov 23 '12 at 14:32
  • in which case/when and why do you want to generate a 404 page? – fischi Nov 23 '12 at 15:45
  • I've needed to do this on at least 2 different occasions. Most recently was making legacy author pages give a 404. It's also something that I'm sure I'll need again in the future. – dave1010 Nov 26 '12 at 10:24
function generate_404_somehow() {
   global $wp_query;
   $wp_query->is_404 = true;

Of course, that will send all of you page to the 404 template. I don't know what the conditions are that this should fire or not fire.

Or to be more cautious (see comments) ...

function generate_404_somehow() {
   global $wp_query;
  • This works but $wp_query->set_404() also runs $wp_query->init_query_flags(), which sets all the other is_* flags to false. – dave1010 Nov 23 '12 at 14:51
  • True, but I don't see the need for the (very minor) overhead. I would be interested to know if there is a case where this doesn't work. I can't find one. – s_ha_dum Nov 23 '12 at 15:04
  • I need to make sure that things like is_single() and is_archive() return false, so any hooks that check them are correct and don't add extra stuff to the 404 page (like the "Next" and "Previous" links). This depends on plugins and themes though. – dave1010 Nov 23 '12 at 15:23
  • 1
    I understand the caution. Using $wp_query->set_404() inside my function should cover it. I assume that that is what you decided to do. – s_ha_dum Nov 23 '12 at 15:32

The other by s_ha_dum answers doesn't set the HTTP Header Status to 404 Not Found. To do this adds status_header( 404 ) to the function.

function generate_404_somehow() {
    global $wp_query;
    status_header( 404 );

What seems to work:

global $wp_query;
$wp_query->max_num_pages = 0; // stop theme from showing Next/Prev links

This seems to set the HTTP headers and load the right template (with is_404() being true).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.