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.

Currently I'm trying to get the post type labels plural. In detail:

$GLOBALS['wp_post_types'][ get_current_screen()->post_type ]->labels->name

This is how I'm trying to retrieve it - in the admin UI - using the public wp API functions:

$post_type_name = get_current_screen()->post_type;
$post_type_obj = get_post_type_object( $post_type_name );
get_post_type_labels( $post_type_obj );

The result is the following Error:

Fatal error: Cannot use object of type stdClass as array in D:\development\xampp\htdocs\wp_inst\wp-includes\post.php on line 1209

The problem is that the post type objects labels is also an object, while get_post_type_labels() calls _get_custom_object_labels() internally and seems to expect an array.

Fun are the last two lines of the _get_custom_object_labels() function:

$labels = array_merge( $defaults, $object->labels );
return (object)$labels;

So, am I using the wrong functions? Is the core function wrong? Is this core function only meant to be used during custom post type registration?


Note: Currently on WP version 3.3.2.

share|improve this question
1  
I'm not completely sure what the best / correct way to do it is, but I've definitely seen this exact same behavior. –  Pippin May 13 '12 at 17:32
add comment

3 Answers 3

up vote 3 down vote accepted

Edit:

get_post_type_labels was never intended to be a public function. It is only used internally when registering a post type. See these trac tickets:


Like you mentioned in your question you can get the labels directly from the globals:

function c3m_get_labels() {
    global $wp_post_types;
    $post_type_name = get_current_screen ()->post_type;
    $labels = &$wp_post_types[$post_type_name]->labels;
    return $labels;
}

Running the function:

$labels = c3m_get_labels();
    var_dump($labels);

Returns:

object(stdClass)[232]
  public 'name' => string 'Posts' (length=5)
  public 'singular_name' => string 'Post' (length=4)
  public 'add_new' => string 'Add New' (length=7)
  public 'add_new_item' => string 'Add New Post' (length=12)
  public 'edit_item' => string 'Edit Post' (length=9)
  public 'new_item' => string 'New Post' (length=8)
  public 'view_item' => string 'View Post' (length=9)
  public 'search_items' => string 'Search Posts' (length=12)
  public 'not_found' => string 'No posts found.' (length=15)
  public 'not_found_in_trash' => string 'No posts found in Trash.' (length=24)
  public 'parent_item_colon' => null
  public 'all_items' => string 'All Posts' (length=9)
  public 'menu_name' => string 'Posts' (length=5)
  public 'name_admin_bar' => string 'Post' 

Alternate use without needing global $wp_post_types:

function c3m_get_labels() {
    $post_type_name = get_current_screen ()->post_type;
    $post_type_obj = get_post_type_object ( $post_type_name );
    return $post_type_obj;
}

Running the function:

$labels = c3m_get_labels();
    $labels = $labels->labels;
    var_dump($labels);

After doing several tests I have concluded that it is impossible to use get_post_type_labels passing the $post_type_object as specified in the codex. So it seems the only use for get_post_type_labels is internally in core when a post type is registered.

share|improve this answer
    
Ok, Thanks. I updated the Codex and hope the ticket goes in. Marked as solution, +1 and thanks. –  kaiser May 13 '12 at 22:30
add comment

This works...

$object = get_post_type_object( 'post' );

echo $object->labels->name;
echo $object->label;

// returns plural name = posts

// var_dump ( $object ); to return all items within the object
// In this instance you can access anything within the class by `$object-> ??? -> ???`

This works...

$object = get_post_type_object( 'post' )->labels;

echo $object->name;

// returns plural name = posts
// in this instance you have access to the labels array only within the object

This works too (but why would you bother...)

$post_type_obj = get_post_type_object( 'post' )->labels;
$object = get_post_type_labels( $post_type_obj );

echo $object->name;

// returns plural name = posts

This also works,

$post_type_obj = get_post_type_object( 'post' );
$object = get_post_type_labels( $post_type_obj->labels );   

echo $object->name;

// returns plural name = posts

...and does prove that it is entirely possible to use get_post_type_labels in themes/plugins passing the post_type_object but as I've been saying the Codex does not tell you to specify what ->attributes within the object you want to access, hence you receive the error;

Fatal error: Cannot use object of type stdClass as array in C:\xampp\htdocs\wp-includes\post.php on line 1209

Wrapping your code into a function is also a solution should your use-case permit or warrant that.

Any of the above is perfectly acceptable whether its in a function or not, they are still performing the same mechanics and are susceptible to the same problems if the core were to change.

share|improve this answer
    
No, that outputs the mentioned error. You don't even have to echo to crash your installation :) –  kaiser May 13 '12 at 17:19
    
Passing $post_type_object to get_post_type_labels will not work being that you are trying to pass a class object as an array, so by dropping get_post_type_labels you can just pluck what you want from the object directly. –  userabuser May 13 '12 at 17:54
    
I understand your thoughts. As you can see from the Q, I already know where I can get it directly from the globals, but that's not what I'm after. I just want to know why the hell there's an API function in core, that doesn't work with the way core builds his globals, but still tries to retrieve it from the global... Anyway +1 for your effort :) –  kaiser May 13 '12 at 17:59
    
I've updated both my answers. Notice the change in option 1 where we need to specify the array within the object we want to pass to get_post_type_labels because that function expects an array and not an object. But using option 2 you eliminate an entire line of code. In both instances we are using built in WP functions so I'm not sure what you meant by getting it directly from the globals. –  userabuser May 13 '12 at 18:13
    
I expect an API function let me get back a result without hitting subproperties. Else I could go with this: $GLOBALS['wp_post_types'][ get_current_screen()->post_type ]->labels->name and get the same output without errors. So something in core is simply wrong. –  kaiser May 13 '12 at 18:19
show 3 more comments

I have a number of different event types and wanted to display the event type next to each title in the loop, so I made a very minor modification to userabuser's code:

$object = get_post_type_object( get_post_type() )->labels;
echo $object->name;

So my complete code now looks like this:

<h3><a href="<?php the_permalink(); ?>"><?php the_title(); ?></a> - <?php $object = get_post_type_object( get_post_type() )->labels;
echo $object->name; ?></h3>

And it works just fine. After each title it displays a hyphen and the plural event type.

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.