When register custom post type in WordPress, the most boring work is writing labels for menus and notifications. If your theme has several custom post types, that work will be repeated again and again. In this case, we can avoid duplication by creating a function that handle all the labels and other parameters automatically, and call it with minimum arguments when needed.

This is how I do that:

function rw_register_post_type( $post_type = '', $args = array() )
    if ( empty( $post_type ) )

    $singular = empty( $args['singular'] ) ? $post_type : $args['singular'];
    $singular = str_replace( '_', ' ', $singular );
    $singular = ucwords( $singular );

    $plural = empty( $args['plural'] ) ? "{$singular}s" : $args['plural'];
    $plural = ucwords( $plural );
    $plural_lower = strtolower( $plural );

    $args['labels'] = empty( $args['labels'] ) ? array() : $args['labels'];
    $args['labels'] = wp_parse_args( $args['labels'], array(
        'name'               => $plural,
        'singular_name'      => $singular,
        'add_new'            => __( 'Add New', 'your_textdomain' ),
        'add_new_item'       => sprintf( __( 'Add New %s', 'your_textdomain' ), $singular ),
        'edit_item'          => sprintf( __( 'Edit %s', 'your_textdomain' ), $singular ),
        'new_item'           => sprintf( __( 'New %s', 'your_textdomain' ), $singular ),
        'view_item'          => sprintf( __( 'View %s', 'your_textdomain' ), $singular ),
        'search_items'       => sprintf( __( 'Search %s', 'your_textdomain' ), $plural ),
        'not_found'          => sprintf( __( 'No %s found', 'your_textdomain' ), $plural_lower ),
        'not_found_in_trash' => sprintf( __( 'No %s found in Trash', 'your_textdomain' ), $plural_lower ),
        'parent_item_colon'  => null,
        'all_items'          => sprintf( __( 'All %s', 'your_textdomain' ), $plural ),
        'menu_name'          => $plural,
    ) );

    $args = wp_parse_args( $args, array(
        'public' => true,
    ) );

    register_post_type( $post_type, $args );

How to use

Simple example: NO arguments

rw_register_post_type( 'book' );
rw_register_post_type( 'movie' );

This will register custom post type book and create singular label Book as well as plural label Books and apply to menu items and notifications.

Different types of plural label

rw_register_post_type( 'company', array(
    'plural' => 'companies',
) );
rw_register_post_type( 'box', array(
    'plural' => 'boxes',
) );

The plural argument is used when you need to specified plural label, in case it’s not auto generated by adding s to singular label.

Handle other arguments

rw_register_post_type( 'company', array(
    'hierarchy' => 'true',
    'public' => false,
) );

This function can handle all default WordPress arguments used by register_post_type function. All arguments are optional. By default it uses only public => true.

Hope this is helpful for you, any feedback is welcomed.


  1. Love the way register post type made easy. Custom Post Type is not only usefull but also “tricky”, and somehow a little bore (writing like-code lines).
    Thanks a lot Tran :)

  2. Excellent job, thanks for your hard work.

  3. Thomas Scholz

    May 26, 2012 at 4:19 AM

    Some languages use up to four different plural forms. Since you don’t even provide a context parameter – what should translators do when you register two post types with the same text domain?

    • Tran Ngoc Tuan Anh

      May 27, 2012 at 3:07 AM

      Hi Thomas, I’m not sure about those languages, can you give me an example? Thanks.

      • Thomas Scholz

        May 27, 2012 at 3:36 AM

        See http://mylanguages.org/polish_plural.php for multiple language forms.

        But the problems with your approach start much earlier.
        Given your examples ‘book’ and ‘movie’: In German I had to translate ‘New %s’ as:

        • Neues Buch (for a book)
        • Neuer Film (for a movie)

        Impossible when I get just one string for both.

        • Thomas Scholz

          May 27, 2012 at 3:37 AM

          Ehm … that should be *multiple plural forms*. :)

        • Tran Ngoc Tuan Anh

          May 27, 2012 at 4:38 PM

          I understand. I know Russian, and it has the same problem. Looks like this “quick” method is not as “quick” solution for all cases.

Leave a Reply

Your email address will not be published.