WordPress Capabilities with Custom Roles and Post Types

This is a brief tutorial about how to setup a custom post type, custom roles and capabilities in WordPress. The end result is a site where a user can be assigned to a role with capabilities to publish, edit, and delete your custom post type and access to other post types, site settings and options is restricted. This article assumes you have a basic understanding WordPress, hooks, themes, and how to edit your theme’s functions.php file and the differences between WordPress’s different post types.

Custom Post Types

Creating a custom post type in WordPress can be accomplished a number of ways. There are many great plugins for custom post types, or you can create them within your theme’s functions.php file directly with the “register_post_type” function. In this tutorial we’ll be working with the WordPress theme directly for the custom post types. Post types could also be defined in a custom plugin, or in a separate “post-types.php” file that could be included within the theme’s functions.php.

A new “zzz_book_init” function to register a “Book” post type will be created and hooked into WordPress’s “init” action. Start by opening your theme’s functions.php file. Your function names can be anything you would like, make sure it is unique so it does not conflict with any built in WordPress or other theme and plugin functions.

The “add_action” function hooks your function on a specific WordPress action. in this case the “zzz_book_init” function is hooked into the “init” action.

The init action runs after WordPress has finished loading but before any headers are sent. Useful for intercepting $_GET or $_POST triggers.

So that means every time WordPress loads up it will make sure our custom post type is registered.

Labels

The $labels array is just a list of the custom post type names used in various contexts throughout WordPress. Choosing good labels helps your post type fit in with the rest of the site.

 Arguments

The $args array contains a list of, well arguments or parameters for the custom post type. The $labels array is also included with the arguments. Keeping the labels in separate array helps with readability and makes things a little easier to maintain. Check out the register_post_type documentation for an in-depth explanation of each argument. Note the capability_type argument, we’ll be working with this in part 2. When capability type is set to ‘post’, this post type has all the same permissions / capabilities as the standard WordPress ‘post’ type. We’ll be creating a custom capability_type and a setup of custom capabilities to go with it.

The code below will get you started with a custom post type.

Full snippet to add to your theme’s functions.php file.

add_action( 'init', 'zzz_book_init' );
/**
 * Register a book post type.
 *
 * @link http://codex.wordpress.org/Function_Reference/register_post_type
 */
function zzz_book_init() {
	$labels = array(
		'name'               => _x( 'Books', 'post type general name', 'your-plugin-textdomain' ),
		'singular_name'      => _x( 'Book', 'post type singular name', 'your-plugin-textdomain' ),
		'menu_name'          => _x( 'Books', 'admin menu', 'your-plugin-textdomain' ),
		'name_admin_bar'     => _x( 'Book', 'add new on admin bar', 'your-plugin-textdomain' ),
		'add_new'            => _x( 'Add New', 'book', 'your-plugin-textdomain' ),
		'add_new_item'       => __( 'Add New Book', 'your-plugin-textdomain' ),
		'new_item'           => __( 'New Book', 'your-plugin-textdomain' ),
		'edit_item'          => __( 'Edit Book', 'your-plugin-textdomain' ),
		'view_item'          => __( 'View Book', 'your-plugin-textdomain' ),
		'all_items'          => __( 'All Books', 'your-plugin-textdomain' ),
		'search_items'       => __( 'Search Books', 'your-plugin-textdomain' ),
		'parent_item_colon'  => __( 'Parent Books:', 'your-plugin-textdomain' ),
		'not_found'          => __( 'No books found.', 'your-plugin-textdomain' ),
		'not_found_in_trash' => __( 'No books found in Trash.', 'your-plugin-textdomain' )
	);

	$args = array(
		'labels'             => $labels,
		'public'             => true,
		'publicly_queryable' => true,
		'show_ui'            => true,
		'show_in_menu'       => true,
 		'query_var'          => true,
		'rewrite'            => array( 'slug' => 'book' ),
 		'capability_type'    => 'post',
 		'has_archive'        => true,
		'hierarchical'       => false,
		'menu_position'      => null,
		'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )
	);

	register_post_type( 'book', $args );
}

You will also want to run “flush_rewrite_rules” upon plugin activation. This helps if your post type is not showing up, or if it’s permalinks are not working correctly.

function my_rewrite_flush() {
    flush_rewrite_rules();
}
add_action( 'after_switch_theme', 'my_rewrite_flush' );

Roles and Capabilties

Stay tuned for part 2 where we talk about custom user roles and managing capabilities. Then we will combine the custom post type, roles, and capabilities to setup users who will only have access to this “Book” post type.

Resources: