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.


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.


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() {
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.


Phpbrew – run multiple php versions with ease

phpbrew is a helpful too to run multiple versions of php. Why run multiple versions of php? In this case it was required for upgrading an old legacy site that depended on php 5.2.


Contact Form 7: Thank You Success Messages

How to simply redirect a visitor to a thank you page after submission with Contact Form 7 – add this snippet to your form’s “Additional Settings” textarea.

on_sent_ok: "location.replace('http://example.com/thank-you/');"

See more details here:
Contact Form 7: Thank You Success Messages.

Use Custom Post Widget With Visual Composer | WordPress Web Design & Hosting in Boulder, CO

Use Custom Post Widget With Visual Composer | WordPress Web Design & Hosting in Boulder, CO.

How to Add an Admin User to the WordPress Database via MySQL

Make sure to use the proper prefix for ‘wp_’ if you have a custom database prefix and to follow the existing user capabilities values when manually adding a user to WordPress.

How to Add an Admin User to the WordPress Database via MySQL.

custom post types – Highlighting wp_nav_menu Ancestor Class w/o Children in Nav Structure? – WordPress Development Stack Exchange

add_filter('nav_menu_css_class', 'current_type_nav_class', 10, 2 ); function current_type_nav_class($classes, $item) { $post_type = get_query_var('post_type'); if ($item->attr_title != '' && $item->attr_title == $post_type) { array_push($classes, 'current-menu-item'); }; return $classes; }

This snippet allows you to check if the current menu item has a parent, and various other things to add classes for formatting WordPress navigation menus.

And this link outlines how to check if an item has a parent page.


via custom post types – Highlighting wp_nav_menu Ancestor Class w/o Children in Nav Structure? – WordPress Development Stack Exchange.

Mac keyboard shortcuts

Check out this handy list of Mac keyboard shortcuts for maximum productivity.

Mac keyboard shortcuts – Matt Gemmell.

Free Online Tools For Developers – FreeFormatter.com

Code formatters, validators, encoders, minifiers, snippets and many other useful developer tools

Free Online Tools For Developers – FreeFormatter.com.

Converting AVI to MP4 with ffmpeg

Simple commands to convert video formats:

This command will provide an mp4 of lower quality.

ffmpeg -i input.avi -acodec libfaac -b:a 128k -vcodec mpeg4 -b:v 1200k -flags +aic+mv4 output.mp4

To maintain the video quality try adjusting the parameters: (-crf parameter will control quality – 23 is the ffmpeg default. The lower the number the higher quality the video will be, it will also take longer to convert.

ffmpeg -i input.avi -c:v libx264 -crf 19 -preset slow -c:a libfaac -b:a 192k -ac 2 out.mp4


Another tip for converting mkv files to mp4.

avconv -i input.mkv -codec copy output.mp4

FFMPEG Resources

CSS Media Queries for common devices

CSS Media Queries for common devices | Code-Tricks.