I recently published a blog post on LimeCuda about User Experience (UX) design and the simplest way to start integrating it into web projects.
However, within WordPress, one aspect of UX that we commonly ignore is the experience the site administrator will have in managing the custom websites that we build.
For these custom developments, we are using WordPress as a full fledged Content Management System (CMS). And, as a CMS, I believe WordPress’ greatest asset is the ability to create new Custom Post Types (CPTs) to manage the different types of content for the site.
Being intentional with our Custom Post Types
Creating CPTs to manage content will greatly increase the usability of your developments when compared to attempting to organize all the content within the default posts and pages. However, we need to be careful in how we integrate CPTs to ensure we’re not taking a great asset for usability and turning it into a road block.
This is the introductory post in a series on CPTs. The goal of this series will be to dig into the options for registering new CPTs and learn how to customize them to meet the specific needs of the content they will house.
Where do the problems begin?
When creating CPTs, we’ve all seen the following code:
add_action( 'init', 'codex_book_init' );
/**
* Register a book post type.
*
* @link http://codex.wordpress.org/Function_Reference/register_post_type
*/
function codex_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 );
}
It’s the example used within the Codex and the most common structure I’ve seen when updating old sites, modifying themes, or glancing through other tutorials. This example works, and at the end of the day there’s nothing wrong with it from a technical perspective.
So what’s the big deal?
Take a second and think about this, what if you considered “register_post_type()” to be nothing more than a basic template for your new content type?
When was the last time you activated a new WordPress template and left the default branding and colors that it came with? It wouldn’t make sense!
It’s the same with “register_post_type()“. You can’t use the default settings and expect it to make sense with all of the new content types you’re creating. If you do, you’re adding unnecessary confusion and road blocks for the users that will be adding the content to your new CPT.
Putting it into perspective
Since this is a series, I want to start with a real-world example that we can build upon throughout the whole series.
To start, I want to create a Back to the Future fan site (OMG!! did it really take me that long to bring up BTTF?) that has a page to show profiles for all of the main characters in the movies. The profiles will include:
- the character name
- the actor’s name
- their headshot
- and a brief description of the character
This would be a perfect time to use a new CPT.
So, using the code above, I would get an admin screen that looks like this:
Not bad right? But, if given the information listed above to add to each of the profiles, can you honestly say you would be completely confident on where to start? I couldn’t either.
So how do we make this better?
My approach is – the more user training that’s required, the bigger the failure of design/UX.
We make extensive use of Advanced Custom Fields to completely customise the CPT experience into a logical content flow for site editors. I would love to see this level of flexibility available in the core.
I’m interested to see where you take this discussion.
PS I was also home edumacated and the coolest kid in my high school 🙂
Peter,
haha! Homeschoolers will rule the world!
I definitely agree on that first point. User training can be so much easier than we typically let it be. Sometimes just naming things properly and giving content it’s own home makes a world of difference.
I also love using ACF and will be bringing that up in a later post in this series. I know some people have a beef with it and have started switching over to CMB from WebDev. I haven’t made the transition yet but I do like the idea of moving the creation of custom fields out of the dashboard.