The Ultimate Guide to Roles and Capabilities in WordPress

The concept of WordPress roles and capabilities can be confusing, so lets take a few minutes to decipher the lingo and make sense of them. As a bonus I will also show you how to implement roles and capabilities in plugins.
Share on facebook
Share on twitter
Share on email
Share on facebook
Share on twitter
Share on email

The concept of WordPress roles and capabilities can be confusing, so lets take a few minutes to decipher the lingo and make sense of them. As a bonus I will also show you how to implement roles and capabilities in plugins.

Roles are what users are grouped by in WordPress. They’re a way of giving a label to various sets of users. One of the most important things to note is that roles are not hierarchical. For example, an administrator is not necessarily “higher” than an editor. Roles are merely defined by what the role can and can’t do. It’s a permissions system.

Capabilities are that permissions system. Roles are assigned capabilities that define what that role can or can’t do. These can be set up with the WordPress defaults or be completely custom, depending on the site. As a plugin developer, you can’t make too many assumptions about what certain roles have permission to do.

WordPress ships with five default roles, which work well for most installs. Although roles are not hierarchical, the default roles do set up what appears to be a hierarchical system.

Administrator — Has control over everything on the site

Editor — Has publishing permission and editing access over everyone’ s posts

Author — Has publishing access and can edit its own posts but doesn’ t have control over others’ content

Contributor — Can submit posts but not publish them

Subscriber — Enables access to edit its user profi le and the WordPress dashboard

It is important to note that while these roles each come with a pre-defined set of capabilities, they can very easily be changed through code or by using a plugin such as Members. That means we can never assume that any of these roles has particular capabilities, although it is usually safe to assume that the ‘Administrator’ role has full rights/capabilities over the website.

The Capability vs Role table on WordPress.org can help you understand better what capabilities are assigned to roles in a default installation.

Since we can never assume much about roles, it is much safer to check for capabilities when defining who has access to an area of the site or not. We’ll come to that in a moment though.

Adding Custom Roles

First of all, dig into some code to learn how we can define custom roles. These can be useful for some plugins or custom functionality for a client. For example, most e-commerce plugins define custom roles such as ‘Shop vendor’ or ‘Shop Manager’, and these would have specific capabilities related to the e-commerce functionality on the site. A similar scenario presents itself for forum plugins, with roles such as ‘Forum Administrator’ and ‘Forum Member’, both of which obviously necessitate different capabilities.

Right, so how do we add a custom role and assign it a few capabilities? Here’s the code you need:

So here we’ve created a new role called ‘Advanced contributor’ and given it two capabilities, ‘edit_posts’ and ‘read’.

That code can be used within a plugin or within your theme’s functions.php file, although I always recommend you create a plugin for custom functionality on a client site. While we’re at it, I suggest using the excellent Pluginception for creating custom functionality within a plugin on your site.

Adding Custom Capabilities

Now that we’ve learnt how to create custom roles, how about learning how to create custom capabilities? Again, it’s a simple thing:

If you want to add a capability to a particular user, rather than to a particular role, use the following code:

When adding a custom role or custom capability, the information is saved to the database (in table wp_options, field wp_user_roles), so it might be better to run this on theme/plugin activation.

Checking for Capabilities

We can check whether a particular user has been assigned a capability, like so:

https://gist.github.com/jgalea/5983390To help you get the ID of the user you want to perform the check against, you can use the Reveal IDs plugin.

The check can also be performed on the current user:

Custom Post Types and Capabilities

When registering a custom post type, you can also define capabilities that will be needed to interact with this post type.

By default, seven keys are accepted as part of the capabilities array:

  • edit_postread_post, and delete_post are meta capabilities, which are then generally mapped to corresponding primitive capabilities depending on the context, which would be the post being edited/read/deleted and the user or role being checked. Thus these capabilities would generally not be granted directly to users or roles.
  • edit_posts – Controls whether objects of this post type can be edited.
  • edit_others_posts – Controls whether objects of this type owned by other users can be edited. If the post type does not support an author, then this will behave likeedit_posts.
  • publish_posts – Controls publishing objects of this post type.
  • read_private_posts – Controls whether private objects can be read.

These four primitive capabilities are checked in core in various locations.

There are also seven other primitive capabilities which are not referenced directly in core, except in map_meta_cap(), which takes the three aforementioned meta capabilities and translates them into one or more primitive capabilities that must then be checked against the user or role, depending on the context.

  • read – Controls whether objects of this post type can be read.
  • delete_posts – Controls whether objects of this post type can be deleted.
  • delete_private_posts – Controls whether private objects can be deleted.
  • delete_published_posts – Controls whether published objects can be deleted.
  • delete_others_posts – Controls whether objects owned by other users can be can be deleted. If the post type does not support an author, then this will behave like delete_posts.
  • edit_private_posts – Controls whether private objects can be edited.
  • edit_published_posts – Controls whether published objects can be edited.

These additional capabilities are only used in map_meta_cap(). Thus, they are only assigned by default if the post type is registered with the 'map_meta_cap' argument set to true (default is false).

I guess that you might be somewhat confused after reading that. Lets try to clear things up a little bit.

The key is knowing the difference between meta capabilities and primitive capabilities.

Primitive capabilities are flags, always set to yes or no. Meta capabilities require some context, like “Is the user the author of this post?”.

Meta capabilities need to be defined with the map_meta_cap filter.

Some other facts:

  • Primitive capabilities are assigned to user roles.
  • Meta capabilities never should be assigned to a role.
  • Primitive capabilities are generally plural, meta capabilities are singular.

Here’s a typical code snippet where we are creating a custom post type and settings its capabilities:

The capability_type and capabilities arguments for the $args array in the register_post_type() function enable you to control custom capabilities. capability_type gives you global control over the capabilities. The capabilities argument is an array that gives you specific control over individual capabilities.

When you register a custom post type, you’re not registering new capabilities, so a roles management plugin such as Members wouldn’t recognize them as such. Capabilities have to be attached to a role/user for them to “exist,” so to speak.

You won’t have access to things with custom caps unless you literally assign these caps through the role editing screen (Members plugin). That means typing them rather than checking the boxes.

If you use post for the capability_type, all is right with the world because you’re just using something that’s already set up. But, if you’re using something custom…well…it’s custom. You’ll have to do a little legwork.

Meta capabilities (the equivalent of edit_postdelete_post, and read_post) aren’t mapped for a custom capability type. You have to do the mapping for these yourself.

Essential Plugins for Roles and Capabilities

Members

A free plugin from Justin Tadlock. Members is a plugin that extends your control over your blog. It’s a user, role, and content management plugin that was created to make WordPress a more powerful CMS.

The foundation of the plugin is its extensive role and capability management system. This is the backbone of all the current features and planned future features.

Map Cap

Mao Cap is ideal if you are using custom post types and want to restrict access to these types to only certain roles.

Other Interesting Reads

If you have an offending plugin that is appearing on certain roles for which it shouldn’t appear, read our previous article on how to remove menu items in admin depending on user role.

We’ve been adding roles and capabilities, but how about deleting them? It’s a bit tricky, but check out this article that explains how to delete unwanted WordPress custom capabilities.

If you enjoyed this post, make sure to subscribe to WP Mayor’s RSS feed.

Table of Contents
Our Sponsors

Fantastic giveaways & incredible discounts.

See all offers →

Our sponsors

17 Responses

  1. Hi. Great article.

    Is it possible to create a role where the user can create and edit (theirs and others) pages and posts but NOT publish them live?

    My client wants to allow their staff to edit all of the pages and posts but they cant publish it live. Only an Administrator can do that?

    I couldn’t get this happening with the ‘Members’ plugin by Justin Tadlock. Was wondering if this is possible.

    Cheer

  2. Hi. nice article bro.But i have a question. If i want to grab a specific function of plugin (for example i want that Editor can edit contact form 7 plugin), how can i do this?

    Thx and sorry for my bad english 😀

  3. it suggest many times in the codex not to use admin_init as the hook but to use the theme change as the hook to adapt user capabilities.

  4. Thank you for your awesome article. I have a question about controlling views. I want to allow only author and his superior can view his/her published post.

  5. Hi,
    Does WordPress support two or more roles for a single user?
    Recently we are trying to create LTI (Learning Tool interoperability) for our plugin and we were asked if our plugin supports multiple roles for a single user.
    Thanks!
    Shiv

  6. @Shivaprakash A Ramaswamy: would love to know this too. Can you post, if you found a way, please. I have the problem that I cant change the author of a post (as admin) since the authors have a custom role and it would be needed for them to have Editor rights as well

    1. WordPress does technically support the idea of more than one role per user by using WP_User::add_role, however, WordPress doesn’t provide a UI for such things. The user role changer on the WordPress Profile page only allows for a user with one role.

  7. Thanks for this great article. I am trying to find a function to update a users role via functions.php

    Do you know if it’s possible?

  8. Hi, I just want to make users can make post but cant edited the content after the post approved. How I supposed to do?
    Thanks

  9. “capability_type gives you global control over the capabilities. The capabilities argument is an array that gives you specific control over individual capabilities.”

    Then, why use the two together?
    We are global or we are specicic …

    One thing I don’t understand about the two argument: do they should be used the two together? for me, if you specify something in ‘capability_type’, why overwrite it in ‘capabilities’ argument?

Leave a Reply

Your email address will not be published. Required fields are marked *

Stay up-to-date with the Mayor
Sign up to receive one weekly email about our latest reviews, tutorials, giveaways and more.

Black Friday Deals

Amazing offers on plugins,
themes, hosting & more!