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've got a custom post type with a standard tag taxonomy added to it like so: 'taxonomies' => array('post_tag'). I've added some tags to some posts of this CPT which are display on the front-end with the template tag the_tags() and the links it generates have this format http://local.mysite.dev/tag/tag1/. When I click such a link a page without any posts is generated using the tag.php template, but if I add ?post_type=seron_mycpt to the end of the URL like so http://local.mysite.dev/tag/tag1/?post_type=seron_mycpt a page with the relevant posts is generated using the same template but this time I also get these lines added to debug.log:

PHP Notice:  Undefined property: stdClass::$labels in /...sitepath.../wp-includes/general-template.php on line 665
PHP Notice:  Trying to get property of non-object in /...sitepath.../wp-includes/general-template.php on line 665

These notices are produced when wp_title() is called in the header.php template. According to the rewrite rules the request is transformed into the query tag=tag1&post_type=seron_mycpt.

For debugging I put print_r(get_queried_object()); in header.php and got this:

MYSITEstdClass Object
(
 [term_id] => 27
 [name] => tag1
 [slug] => tag1
 [term_group] => 0
 [term_taxonomy_id] => 27
 [taxonomy] => post_tag
 [description] =>
 [parent] => 0
 [count] => 2
)

I think WP expects a CPT object with a labels property but gets this object instead which doesn't have that property.

If I tag an ordinary post with the same tag, the same header.php and tag.php templates are used and that post is displayed when using the http://local.mysite.dev/tag/tag1/ URL, and in that case no PHP notices are produced in debug.log, although print_r(get_queried_object()) shows a very similar object. Maybe WP never reaches the notice-producing line in general-template.php.

I don't understand what this object is and why it is passed instead of a CPT object. Could someone explain?

share|improve this question
add comment

3 Answers

up vote 5 down vote accepted

This is a bug (one that I've encountered before) and could do with a ticket in trac (since I never took the time to submit one!)

The trouble starts with requests that set multiple is_* query flags as true (specifically flags that represent objects, such as single posts, pages, and post type & term archives).

This is because there can only ever be one "queried object" (in your case it's the term).

Now the reason wp_title() seems to throw a wobbly is down to another function it calls:

function post_type_archive_title( $prefix = '', $display = true ) {
    if ( ! is_post_type_archive() )
        return;

    $post_type_obj = get_queried_object();
    $title = apply_filters('post_type_archive_title', $post_type_obj->labels->name );

    if ( $display )
        echo $prefix . $title;
    else
        return $title;
}

Since the is_post_type_archive flag is true, it assumes the queried object is a post type, and tries to access an undefined property of what is actually a term object.

Whether the fix is to open up the possibility of multiple queried objects, or to implement more rigourous checking of them, I'm not sure, but I'll get it on trac & we'll see what follows.

Update: To suppress the error (& possible others), "switch off" one of the flags:

add_action( 'parse_query', 'wpse_71157_parse_query' );
function wpse_71157_parse_query( $wp_query )
{
    if ( $wp_query->is_post_type_archive && $wp_query->is_tax )
        $wp_query->is_post_type_archive = false;
}
share|improve this answer
    
Found an existing ticket - use this to submit any comments/patches. –  TheDeadMedic Nov 1 '12 at 16:33
    
Thanks for the confirmation and the ticket. –  seron Nov 1 '12 at 22:13
    
I read in this comment in a related ticket that a filter can be used to rebuild the title but the commenter doesn't elaborate. I've never created a filter myself. Any idea how to do this? –  seron Nov 1 '12 at 22:39
    
I assume they're referring to the wp_title filter that the function wp_title() applies before output - but that still wouldn't suppress the notice (see update for how to do just that). –  TheDeadMedic Nov 1 '12 at 23:39
1  
Thank you. That fixed both the title and suppressed the notices, like you said. I modified it slightly to check is_tag instead of is_tax, and learned a lot in the process. –  seron Nov 2 '12 at 8:20
add comment

Here is what I did. In my taxonomy archive template I was relying on is_post_type_archive() to output additional div tags.

add_action( 'parse_query', 'orb_parse_query' );

function orb_parse_query( $wp_query ) {  
    global $post_type_obj;

    if ( $wp_query->is_post_type_archive && $wp_query->is_tax ) {
        $post_type_obj = get_queried_object();

        if (empty($post_type_obj->labels)) {
            $post_type_obj->labels = new stdClass();
            $post_type_obj->labels->name = 'dev/hack to fix WordPress Bug';
        }
    }
}
share|improve this answer
add comment

Thanks all for help. I used solution from lordspace and little modified it, to show the name of the current custom post type.

add_action( 'parse_query', 'orb_parse_query' );

function orb_parse_query( $wp_query ) {  
    global $post_type_obj;

    if ( $wp_query->is_post_type_archive && $wp_query->is_tax ) {
        $post_type_obj = get_queried_object();

        if (empty($post_type_obj->labels)) {
            $currentPostType = $wp_query->query['post_type'];
            $currentPostTypeName = get_post_type_object($currentPostType)->labels->name;
            $post_type_obj->labels = new stdClass();
            $post_type_obj->labels->name = $currentPostTypeName;
        }
    }
}
share|improve this answer
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.