public
Created

Help file when registering post types.

  • Download Gist
register-post-type.php
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257
<?php
 
/* 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). */
'title',
 
/* Post content ($post->post_content). */
'editor',
 
/* Post excerpt ($post->post_excerpt). */
'excerpt',
 
/* Post author ($post->post_author). */
'author',
 
/* Featured images (the user's theme must support 'post-thumbnails'). */
'thumbnail',
 
/* Displays comments meta box. If set, comments (any type) are allowed for the post. */
'comments',
 
/* Displays meta box to send trackbacks from the edit post screen. */
'trackbacks',
 
/* Displays the Custom Fields meta box. Post meta is supported regardless. */
'custom-fields',
 
/* Displays the Revisions meta box. If set, stores post revisions in the database. */
'revisions',
 
/* Displays the Attributes meta box with a parent selector and menu_order input box. */
'page-attributes',
 
/* Displays the Format meta box and allows post formats to be used with the posts. */
'post-formats',
),
 
/**
* 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. */
register_post_type(
'example', // Post type name. Max of 20 characters. Uppercase and spaces not allowed.
$args // Arguments for post type.
);
}
 
?>

Hiya, love this template for cpts!

I am just wondering whether there is a specific reason why you didn't include the register_meta_box_cb and taxonomies (optional) arguments.

I'd be very interested to hear your opinion.

Smile,
Juliette

Another small note - on the rewrite -> feeds argument explanation:
/* Whether to create feeds for this post type. */

This is incorrect. The feed will be always be offered by WP in the cpt context. This setting only determines whether WP will offer pretty links for the feed, i.e.:
true would result in feed links looking like: examples/feed/
false would result in feed links looking like: examples/?feed=rss2

I am just wondering whether there is a specific reason why you didn't include the register_meta_box_cb and taxonomies (optional) arguments.

For taxonomies, 99% of the time, I'd never do that. The only cases I've found it useful is when using the category or post_tag taxonomies, which I wouldn't use for most CPTs. For custom taxonomies, you just add the post type in register_taxonomy().

For the meta box callback, I've just never really used it. It can be useful. I typically just roll my own meta boxes on the add_meta_boxes_{$post_type} hook, which is located in some admin-only file in my plugin. Having the callback defined in a completely separate file where I register the post type can be tough to hunt down sometimes.

Another small note - on the rewrite -> feeds argument explanation:

Yeah, that should be "Whether to create pretty permalinks for feeds."

@justintadlock You can still edit the Gist...

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.