I understand that although not used by core in any way you can set a description for a CPT:

$args = array(
   'description' => "My CPT description"
register_post_type( 'my_cpt', $args );

You can then access it like that:

get_post_type_object( 'my_cpt' )->description;

But that leaves us directly accessing a property with no way to filter it. Am I correct that this is in fact the way it is and the only way to have this filterable is to introduce a function with a filter to access it myself?

Aside: I have seen this but it kind of solves the use case but by actually not using the CPT description any more.

EDIT: Okay I need to clarify - I'd like to filter it when requested and not always which is not possible with registered_post_type as birgire suggested. I am trying to make the description user editable (also see this as linked above). But if I e.g. store the description as an option I do not want to request this option on each page load if it is only rarely needed.

1 Answer 1


Since WP 3.3, there's an action to modify a registered post type after registration.

do_action( 'registered_post_type', $post_type, $args );

The $post_type is the post type object and there doesn't happen much after the post type object gets stuffed in the global and before the callbacks attached to this action execute. In fact it's (with WP 4.0) just the connection between a post type and its taxonomies that gets set.

As the description is not really any (public) use case, doesn't get registered as part of the (filterable) labels and doesn't get stuffed into the DB - only registered during runtime at the global - it's say it's pretty safe to just alter the description there. Benefit is that you are just re-setting a single value in a pretty small global array. So there should be not notable performance decrease.

When you look at get_post_type_object(), which is the default entry point to grabbing data from the (C)PT, then it's also just calling the global:

function get_post_type_object( $post_type ) {
    global $wp_post_types;

    if ( empty($wp_post_types[$post_type]) )
        return null;

    return $wp_post_types[$post_type];

I'd suggest the following:

/** Plugin Name: (#160620) Alter {$CPT}-post type description */
add_action( 'registered_post_type', function( $pt, $args )
    if ( ! in_array( $your_cpt, get_post_types( array( '_builtin' => false ) ) ) )

    $GLOBALS['wp_post_types'][ $pt ]['description'] = 'I changed.';
}, 0, 2 );
  • 2
    Please, fix the errors in your code, I can't edit it, but the _built_in paramenter should be _builtin, and you are missing a quote in the action name.
    – Tomás Cot
    Sep 8, 2014 at 17:10
  • @TomásCot Thanks for pointing that out. Btw, you can file an edit. It will just go into the review queue and get approved. IIRC you even get +2 rep points for each upvote on the answer if your edit was accepted.
    – kaiser
    Sep 8, 2014 at 17:13
  • the edit wasn't long enough.
    – Tomás Cot
    Sep 8, 2014 at 17:14
  • 1
    @TomásCot When I didn't have the reputation to just edit anything and the edit wasn't big enough, I just added the string »6chars« to the bottom. Whoever reviews it will remove it, at least there never has been one left behind. I think it is easier that way, because then it's handled. Besides often you find a minor code problem or typo, but the user isn't very active, then you can't ask them to do it. Sep 8, 2014 at 22:01
  • @ialocin I'd prefer if you'd leave a trail of invisible white space or at least at this at the beginning. If you got a history of sane edits, then I only briefly scan what you really did when approving it. :P
    – kaiser
    Sep 8, 2014 at 23:07

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.