Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a 404.php template for my theme. I also have WP_DEBUG in wp-config.php set to TRUE.

Consider this 404 template:

get_header(); ?>

<div id="content" style="full-width">
    <div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
        <div class="post-content">
        Whatever.
        </div>
    </div>
</div>

<?php get_footer(); ?>

I get the following error:

Notice: Trying to get property of non-object in .../path/post-template.php on line 30

Now I know the error is caused by the call to the_ID() on line 4. And the easiest solution would be for me to just remove it in the template.

However, there are places in other template parts, header.php for instance, that either calls the same function or uses $post->ID.

An example would be $project_meta = get_post_meta($post->ID, 'show_project_meta', true);. This is shared and works fine in any other template, i.e where the page has a post/page ID. What can I do for the 404 page?

Is there a way to fix this? Thanks.

share|improve this question
    
The 404 page is the catchall, it only gets called when WP can't find anything else relevant to display (posts for example). Why are you trying to display information about a post from a template file that usually only gets called when there is no relevant post to display in the first place? –  Freddy Dec 5 '12 at 19:29
add comment

2 Answers

The 404.php template file is used for 404 errors: i.e. no posts found.

Since there are no posts, there is no $post object. With no $post object, functions such as the_ID() are not available, and will return the error you're observing.

The fix: replace all instances of $post-derived data with static data. e.g. replace this:

<div id="post-<?php the_ID(); ?>" <?php post_class(); ?>>

...with this:

<div id="post-0" <?php post_class(); ?>>
share|improve this answer
add comment

the_ID is meant for use in the Loop. Even if your Loop starts in get_header not everything is going to have proper loop. It kinda looks like that what is happening, but on the other hand have_posts, which should start your Loop, should mean the Loop doesn't start on that 404 page. That is what happened when I tried it, anyway. So maybe this page just isn't in a Loop at all.

$post is set very early in page loads most of the time. If this isn't in a Loop-- that is, the Loop doesn't start in get_header-- that ID may not be what you expect, or what you want. On a blog index, index.php, that ID is the ID of the first post in the loop, not really the ID of the index page, which doesn't have an ID at all unless you've set the index to a page in the backend. Even then, though, the ID is the first post in the Loop, not the ID of the 'static' page. You will have the same post/Loop problem with $post->ID.

And, of course, most of this is based on guessing at some of your theme/template structure.

Your really should be setting it conditionally like...

if (is_single() {
    $pID = $post->ID;
} elseif (is_search()) {
    $pID = <something>;
} // and so on until you get all the conditions you need

<div id="content" style="full-width">
    <div id="post-<?php echo $pID ?>" <?php post_class(); ?>>

Also, I am pretty sure ids are not supposed to start with a digit. I'd have to look it up, but if memory serves./...

share|improve this answer
    
In contexts where a Loop is instantiated (e.g. via if ( have_posts() ) : while ( have_posts() ) : the_post();) it is perfectly safe/valid to use functions such as the_ID(). The problem is that the 404 template doesn't have or need a Loop, so $post-related functions can't be used in the template. –  Chip Bennett Dec 5 '12 at 19:46
    
Yes, I realized that and edit my post already. –  s_ha_dum Dec 5 '12 at 19:48
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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