I am creating a WP theme with a built in custom post type (and I am using WPAlchemy to add a couple of custom metaboxes).

$theme_custom_metabox = new WPAlchemy_MetaBox(
    'id' => 'my_metabox',
    'title' => 'Custom Metabox',
    'context' => 'normal',
    'autosave' => TRUE,
    'types' => array('post', 'page', 'theme_custom_post_type'), // Can I add all custom_post_types by default here?
    'priority' => 'high',
    'template' => MY_PATH . '/includes/my_theme/metaboxes/my_metabox.php',

Reason: 'Out of the box', WPAlchemny requires you to list the post_types in the 'types' array - this works fine if you know all the post_types being used, but this is a theme to be shipped so the actual CPTs being used would be unknown.

I would like the theme to programmatically add its metaboxes to any custom_post_types the user would add.

I guess the most logical way would be to store all CPTs in a variable. eg:

$all_cpt = all_custom_post_keys();

'types' => $all_cpt,

1 Answer 1


Easy list filtering

There's the global $wp_post_types which is used for e.g. in get_post_type_object( $name );, register_post_type(), etc.

If you want to omit the ones delivered with core, you should filter the returned list and skip everything that has the _builtin key set to true. Just use wp_list_filter() for that

$cpts = wp_list_filter( $GLOBALS['wp_post_types'], array( '_builtin' => false, ) );

Runtime collection

A different way to go at this: At the end of the post type registration (register_post_type()) process, there's an action running:

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

This action maybe is - depending on your use case - a nice place to fetch all post types, as core registers its own post types using create_initial_post_types() which uses register_post_type() by itself. It will also allow you to fetch post types that get registered late.

add_action( 'registered_post_type', function( $pt, $args )
    static $cpts = array();

    if (
        ! $args->_builtin 
        and ! in_array( $args->name, array_keys( $cpts ) ) 
        $cpts[ $args->name ] = $args;

    // here, $cpts gets constant updates as soon as a new post type is registered
    // ignores already added post types by name
    // also ignores cores `_builtin` post types

}, 20, 2 );

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.