9

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.
generate_404_somehow();

// later...
add_action('template_redirect', function() {
    // should be "true"
    var_dump(is_404());
});

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

5
  • Perhaps I could modify the query to search for a non-existent page.
    – dave1010
    Commented Nov 23, 2012 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
    Commented Nov 23, 2012 at 14:32
  • I want to create a 404. I'll edit the question a bit...
    – dave1010
    Commented Nov 23, 2012 at 14:32
  • in which case/when and why do you want to generate a 404 page?
    – fischi
    Commented Nov 23, 2012 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
    Commented Nov 26, 2012 at 10:24

3 Answers 3

8
function generate_404_somehow() {
   global $wp_query;
   $wp_query->is_404 = true;
}
add_action('wp','generate_404_somehow');

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;
   $wp_query->set_404();
}
add_action('wp','generate_404_somehow');
4
  • This works but $wp_query->set_404() also runs $wp_query->init_query_flags(), which sets all the other is_* flags to false.
    – dave1010
    Commented Nov 23, 2012 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
    Commented Nov 23, 2012 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
    Commented Nov 23, 2012 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
    Commented Nov 23, 2012 at 15:32
2

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;
    $wp_query->set_404();
    status_header( 404 );
}
add_action('wp','generate_404_somehow');
1
0

What seems to work:

global $wp_query;
$wp_query->set_404();
$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 and acknowledge you have read our privacy policy.

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