I'm using the following two strips of code to retrieve a list of categories (1st code) then displaying them in a select menu (2nd code), for my theme options page. I was wondering how I could change this code to do the same, but, retrieve custom post types instead??

Code used to retrieve categories

$tp_categories[0] = array(
'value' => 0,
'label' => ''
$tp_cats = get_categories(); $i = 1;
foreach( $tp_cats as $tp_cat ) :
$tp_categories[$tp_cat->cat_ID] = array(
    'value' => $tp_cat->cat_ID,
    'label' => $tp_cat->cat_name

Code used to display categories in a dropdown select menu

<tr valign="top"><th scope="row"><label for="choose_cat">Choose Category</label></th>
<select id="choose_cat" name="tp_options[choose_cat]">
foreach ( $tp_categories as $category ) :
    $label = $category['label'];
    $selected = '';
    if ( $category['value'] == $settings['choose_cat'] )
        $selected = 'selected="selected"';
    echo '<option style="padding-right: 10px;" value="' . esc_attr( $category['value'] ) . '" ' . $selected . '>' . $label . '</option>';

2 Answers 2


There's a core function for that: get_post_types():

<?php get_post_types( $args, $output, $operator ); ?>

So, for example, to return public, custom post types by name:

$custom_post_types = get_post_types( array(
    // Set to FALSE to return only custom post types
    '_builtin' => false,
    // Set to TRUE to return only public post types
    'public' => true
) );
  • This is the only solution I've found to directly address how to omit the default post types. Thanks.
    – verism
    Sep 25, 2014 at 13:52

Use get_post_types() or the global variable $wp_post_types.

From wp-includes/post.php:

 * Get a list of all registered post type objects.
 * @package WordPress
 * @subpackage Post
 * @since 2.9.0
 * @uses $wp_post_types
 * @see register_post_type
 * @param array|string $args An array of key => value arguments to match against the post type objects.
 * @param string $output The type of output to return, either post type 'names' or 'objects'. 'names' is the default.
 * @param string $operator The logical operation to perform. 'or' means only one element
 *  from the array needs to match; 'and' means all elements must match. The default is 'and'.
 * @return array A list of post type names or objects
function get_post_types( $args = array(), $output = 'names', $operator = 'and' ) {
    global $wp_post_types;

    $field = ('names' == $output) ? 'name' : false;

    return wp_filter_object_list($wp_post_types, $args, $operator, $field);

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.