5/26/2014 - 8:20 AM



/* Register custom post types on the 'init' hook. */
add_action( 'init', 'my_register_post_types' );

 * Registers post types needed by the plugin.
 * @since  0.1.0
 * @access public
 * @return void
function my_register_post_types() {

	/* Set up the arguments for the post type. */
	$args = array(

		 * A short description of what your post type is. As far as I know, this isn't used anywhere 
		 * in core WordPress.  However, themes may choose to display this on post type archives. 
		'description'         => __( 'This is a description for my post type.', 'example-textdomain' ), // string

		 * Whether the post type should be used publicly via the admin or by front-end users.  This 
		 * argument is sort of a catchall for many of the following arguments.  I would focus more 
		 * on adjusting them to your liking than this argument.
		'public'              => true, // bool (default is FALSE)

		 * Whether queries can be performed on the front end as part of parse_request(). 
		'publicly_queryable'  => true, // bool (defaults to 'public').

		 * Whether to exclude posts with this post type from front end search results.
		'exclude_from_search' => false, // bool (defaults to 'public')

		 * Whether individual post type items are available for selection in navigation menus. 
		'show_in_nav_menus'   => false, // bool (defaults to 'public')

		 * Whether to generate a default UI for managing this post type in the admin. You'll have 
		 * more control over what's shown in the admin with the other arguments.  To build your 
		 * own UI, set this to FALSE.
		'show_ui'             => true, // bool (defaults to 'public')

		 * Whether to show post type in the admin menu. 'show_ui' must be true for this to work. 
		'show_in_menu'        => true, // bool (defaults to 'show_ui')

		 * Whether to make this post type available in the WordPress admin bar. The admin bar adds 
		 * a link to add a new post type item.
		'show_in_admin_bar'   => true, // bool (defaults to 'show_in_menu')

		 * The position in the menu order the post type should appear. 'show_in_menu' must be true 
		 * for this to work.
		'menu_position'       => null, // int (defaults to 25 - below comments)

		 * The URI to the icon to use for the admin menu item. There is no header icon argument, so 
		 * you'll need to use CSS to add one.
		'menu_icon'           => null, // string (defaults to use the post icon)

		 * Whether the posts of this post type can be exported via the WordPress import/export plugin 
		 * or a similar plugin. 
		'can_export'          => true, // bool (defaults to TRUE)

		 * Whether to delete posts of this type when deleting a user who has written posts. 
		'delete_with_user'    => false, // bool (defaults to TRUE if the post type supports 'author')

		 * Whether this post type should allow hierarchical (parent/child/grandchild/etc.) posts. 
		'hierarchical'        => false, // bool (defaults to FALSE)

		 * Whether the post type has an index/archive/root page like the "page for posts" for regular 
		 * posts. If set to TRUE, the post type name will be used for the archive slug.  You can also 
		 * set this to a string to control the exact name of the archive slug.
		'has_archive'         => 'example', // bool|string (defaults to FALSE)

		 * Sets the query_var key for this post type. If set to TRUE, the post type name will be used. 
		 * You can also set this to a custom string to control the exact key.
		'query_var'           => 'example', // bool|string (defaults to TRUE - post type name)

		 * A string used to build the edit, delete, and read capabilities for posts of this type. You 
		 * can use a string or an array (for singular and plural forms).  The array is useful if the 
		 * plural form can't be made by simply adding an 's' to the end of the word.  For example, 
		 * array( 'box', 'boxes' ).
		'capability_type'     => 'example', // string|array (defaults to 'post')

		 * Whether WordPress should map the meta capabilities (edit_post, read_post, delete_post) for 
		 * you.  If set to FALSE, you'll need to roll your own handling of this by filtering the 
		 * 'map_meta_cap' hook.
		'map_meta_cap'        => true, // bool (defaults to FALSE)

		 * Provides more precise control over the capabilities than the defaults.  By default, WordPress 
		 * will use the 'capability_type' argument to build these capabilities.  More often than not, 
		 * this results in many extra capabilities that you probably don't need.  The following is how 
		 * I set up capabilities for many post types, which only uses three basic capabilities you need 
		 * to assign to roles: 'manage_examples', 'edit_examples', 'create_examples'.  Each post type 
		 * is unique though, so you'll want to adjust it to fit your needs.
		'capabilities' => array(

			// meta caps (don't assign these to roles)
			'edit_post'              => 'edit_example',
			'read_post'              => 'read_example',
			'delete_post'            => 'delete_example',

			// primitive/meta caps
			'create_posts'           => 'create_examples',

			// primitive caps used outside of map_meta_cap()
			'edit_posts'             => 'edit_examples',
			'edit_others_posts'      => 'manage_examples',
			'publish_posts'          => 'manage_examples',
			'read_private_posts'     => 'read',

			// primitive caps used inside of map_meta_cap()
			'read'                   => 'read',
			'delete_posts'           => 'manage_examples',
			'delete_private_posts'   => 'manage_examples',
			'delete_published_posts' => 'manage_examples',
			'delete_others_posts'    => 'manage_examples',
			'edit_private_posts'     => 'edit_examples',
			'edit_published_posts'   => 'edit_examples'

		 * How the URL structure should be handled with this post type.  You can set this to an 
		 * array of specific arguments or true|false.  If set to FALSE, it will prevent rewrite 
		 * rules from being created.
		'rewrite' => array(

			/* The slug to use for individual posts of this type. */
			'slug'       => 'example', // string (defaults to the post type name)

			/* Whether to show the $wp_rewrite->front slug in the permalink. */
			'with_front' => false, // bool (defaults to TRUE)

			/* Whether to allow single post pagination via the <!--nextpage--> quicktag. */
			'pages'      => true, // bool (defaults to TRUE)

			/* Whether to create feeds for this post type. */
			'feeds'      => true, // bool (defaults to the 'has_archive' argument)

			/* Assign an endpoint mask to this permalink. */
			'ep_mask'    => EP_PERMALINK, // const (defaults to EP_PERMALINK)

		 * What WordPress features the post type supports.  Many arguments are strictly useful on 
		 * the edit post screen in the admin.  However, this will help other themes and plugins 
		 * decide what to do in certain situations.  You can pass an array of specific features or 
		 * set it to FALSE to prevent any features from being added.  You can use 
		 * add_post_type_support() to add features or remove_post_type_support() to remove features 
		 * later.  The default features are 'title' and 'editor'.
		'supports' => array(

			/* Post titles ($post->post_title). */

			/* Post content ($post->post_content). */

			/* Post excerpt ($post->post_excerpt). */

			/* Post author ($post->post_author). */

			/* Featured images (the user's theme must support 'post-thumbnails'). */

			/* Displays comments meta box.  If set, comments (any type) are allowed for the post. */

			/* Displays meta box to send trackbacks from the edit post screen. */

			/* Displays the Custom Fields meta box. Post meta is supported regardless. */

			/* Displays the Revisions meta box. If set, stores post revisions in the database. */

			/* Displays the Attributes meta box with a parent selector and menu_order input box. */

			/* Displays the Format meta box and allows post formats to be used with the posts. */

		 * Labels used when displaying the posts in the admin and sometimes on the front end.  These 
		 * labels do not cover post updated, error, and related messages.  You'll need to filter the 
		 * 'post_updated_messages' hook to customize those.
		'labels' => array(
			'name'               => __( 'Examples',                   'example-textdomain' ),
			'singular_name'      => __( 'Example',                    'example-textdomain' ),
			'menu_name'          => __( 'Examples',                   'example-textdomain' ),
			'name_admin_bar'     => __( 'Examples',                   'example-textdomain' ),
			'add_new'            => __( 'Add New',                    'example-textdomain' ),
			'add_new_item'       => __( 'Add New Example',            'example-textdomain' ),
			'edit_item'          => __( 'Edit Example',               'example-textdomain' ),
			'new_item'           => __( 'New Example',                'example-textdomain' ),
			'view_item'          => __( 'View Example',               'example-textdomain' ),
			'search_items'       => __( 'Search Examples',            'example-textdomain' ),
			'not_found'          => __( 'No examples found',          'example-textdomain' ),
			'not_found_in_trash' => __( 'No examples found in trash', 'example-textdomain' ),
			'all_items'          => __( 'All Examples',               'example-textdomain' ),

			/* Labels for hierarchical post types only. */
			'parent_item'        => __( 'Parent Example',             'example-textdomain' ),
			'parent_item_colon'  => __( 'Parent Example:',            'example-textdomain' ),

			/* Custom archive label.  Must filter 'post_type_archive_title' to use. */
			'archive_title'      => __( 'Examples',                   'example-textdomain' ),

	/* Register the post type. */
		'example', // Post type name. Max of 20 characters. Uppercase and spaces not allowed.
		$args      // Arguments for post type.