I can probably list a million reasons I think my recent Members plugin is neat. Not only have I deployed it on about five of my own blogs in the last few days, I’ve also started integrating it with some of my other plugins and themes.
One of the features I feel that’s lacking in most plugins and themes is the ability to define custom capabilities to access certain content. This is one of the reasons I’ve developed this plugin.
If you’re a plugin or theme developer and add admin menus, this tutorial should be helpful. What I’ll be showing you is a way to give users of your plugin smarter control over its settings.
Adding an admin menu page the normal way
There are several functions for adding admin menus, which all work basically the same way. I’ll use add_submenu_page() as an example since it’s fairly common.
When adding a page, you’ll use the function like this:
add_submenu_page( $parent_page, $page_title, $menu_title, $capability, $file, $function );
What we’ll be focusing on here is the $capability variable. Typically, this is hardcoded, but we need to be able to change this. So, when writing that code, you should replace $capability with a filter hook:
add_submenu_page( $parent_page, $page_title, $menu_title, apply_filters( 'plugin_name_capability', $capability ), $file, $function );
plugin_name_capability should be something unique to your plugin. Just leave $capability as whatever capability you would normally use. It can now be changed.
Making this change does two important things:
- Allows users to change the capability if they want to with a filter.
- Allows you to integrate your plugin with the Members plugin.
You can stop reading here and will have done your part in making your plugin more flexible. However, you can offer integration with my Members plugin, which will make it even easier for users to use.
Integrating your plugin/theme with the Members plugin
Here’s where the real neat stuff comes into play. You can run a check to see if the Members plugin is installed. If the plugin is indeed installed, you can create a custom capability just for your plugin’s settings page.
Let’s assume that filter hook was something like this:
apply_filters( 'plugin_name_capability', 'manage_options' );
People without the Members plugin would need the manage_options capability to change the settings for your plugin. To me, that doesn’t sound like a great solution, and it definitely doesn’t offer the site owner much flexibility.
If the Members plugin is installed, we’ll change that capability to something like edit_my_plugin_settings (change to something unique):
if ( function_exists( 'members_plugin_init' ) )
add_filter( 'plugin_name_capability', 'plugin_name_unique_capability' );
function plugin_name_unique_capability( $cap ) {
return 'edit_my_plugin_settings';
}
Now, only users of a role with the edit_my_plugin_settings capability will be able to access that plugin’s page.
Adding the capability to the role edit page
You can offer even more integration with the Members plugin if you like. You can add a checkbox to the Edit Role page that allows users to easily select this capability rather than typing it in.
if ( function_exists( 'members_get_capabilities' ) )
add_filter( 'members_get_capabilities', 'plugin_name_extra_caps' );
function plugin_name_extra_caps( $caps ) {
$caps[] = 'edit_my_plugin_settings';
return $caps;
}
Why is all this important?
Imagine running a site with 20 different writers, publishers, administrators, and so on. Some people of that site need specific access to certain things but no access to other things.
For example, a friend and I are both running this site with all these people. The friend doesn’t need access to the WordPress options, but he does need access to your plugin’s options. Those should be controlled by two separate capabilities rather than one.
I created Members to allow site owners to have as much flexibility as possible. But, the plugin itself can only do so much on its own. As developers in the WordPress community, we can make WordPress infinitely flexible by working together, and I’m definitely trying to make it as easy as possible to integrate other plugins with my own.

Thank you this will come in handy.
You could also achieve the same thing without filters (not because it’s better or worse, just different).
Haven’t had a chance to properly try out this plugin yet Justin but it looks very promising. Keep up the good work.
Catherine Jacobs — I hope so. Let me know if/how you use it.
johnbillion — Yes, that would work for integration with the Members plugin. But, it doesn’t give the user an option to change it without diving into the plugin files or allow for integration with other role/capability management plugins. Of course, I’m fine with integration just with my plugin.
I’d like to suggest an alternative method for this which is simpler and potentially allows effortless compatibility with other role management plugins. I’m not that good at explaining things so bear with me
The aim is to get rid of the
if ( function_exists( '...' ) )checks inside plugins that want to utilise custom capabilities. It makes compatibility with other role management plugins a pain, as you need a check for each role management plugin that’s available. Not ideal.To avoid this, one common filter could be used (in an ideal world this would be used by all role management plugins) that gets filtered by the currently installed role management plugin, not by the plugin that wants to use custom capabilities.
Note the parameters in the call to
apply_filters. The usual parameter is the default capability that will get used when no role management plugin is used. The second is the capability that will get used if there is one (eg. if Members is installed).This method requires the following addition to the Members plugin, but once added would form a solid system for allowing plugins to utilise custom capabilities if any role management plugin such as Members is installed.
This function simply returns the custom capability, nothing else. If this code was used in other role management plugins, plugins would isntantly have compatibility with all the role management plugins without needing to perform a check for each one (the
if ( function_exists( '...' ) )stuff above).Finally, with regard to Adding the capability to the role edit page, if this filter was given a more generic name (such as ‘get_capabilities’ if that doesn’t already exist) then other role management plugins could use this method for adding custom capabilies to a role administration screen.
Suggestions?
(P.S. a Preview button on your blog comment box would be great)
johnbillion — While I like the thinking-outside-the-box mentality you’ve got going here, that won’t work either. Your code makes the assumption that only one admin menu page that only needs a single capability exists for the second plugin. If that were always the case, it be great for doing this with admin menus.
Plugin authors don’t have to use
function_existsif they don’t want to. I marked the point above in the article where they could stop, which is at creating the filter. Then, they could easily pass along a few lines of code to their users to drop in their theme’sfunctions.phpto create custom capabilities.Hmm, not following you here.
The above code could be used multiple times in a plugin wherever a capability check occurs. Eg.:
johnbillion — Ahh. I think my brain has been fried for the past few days.
That’s definitely correct. Having a standard function like that for use across WordPress would be cool. The only problem I see now is that the change needs to be made across two separate plugins rather than one, but that’s not a big deal.
Personally, I’d be happy to see a simple filter hook for the capability in most plugins.
Obviously my suggestion is also an ideal world solution, where every role management plugin uses the same filter and every plugin that wants to allow custom capabilities does the same! I don’t think OSS projects are renowned for having widely implemented standards.
Tell me about it. I’m surprised anything I say at the moment makes sense. I’m working with multiple custom taxonomy intersections in queries (and hoping a patch for WP will come out of it all).
could this be made into a plugin so that different users can be limited to see a different back end… depending on their role?
johnbillion — It’s the ideal-world solutions that get things moving toward standardization, but obviously it’s tough to do.
I’ve checked to see if there was a filter hook on the
add_submenu_page()function but couldn’t find one. Having WordPress implement a hook on admin menus (if there aren’t any already) would be more ideal. I’ll continue my search though to see if I can turn up anything.CG — Not as far as I can tell. That’s what John and I have been discussing here in the comments — some sort of standardization. With that, we could have a lot more flexibility.
And, it wouldn’t be role dependent; it’d be capability dependent.
I agree… I know of a plugin that ‘hides’ some menu items but it does so for everyone including the admin.. pity there’s not something that can hide menus according to XYZ.. that would be ideal…
Thank you for the plugin. It should be very useful with custom capabilities.
Thanks,
Steve
I’m going to sound like a jerk for asking, but as a computer illiterate who likes blogging, is there an easier way to do this? By easier I mean… less hands on…
Steve — If we can get a few more plugin authors on board, it will be extremely useful.
Alfred — If you’re “computer illiterate,” I’m assuming you haven’t written a WordPress plugin. Therefore, this tutorial doesn’t apply to you. This is for plugin/theme developers to implement within their plugins/themes, not for end users.
Without modifying a plugin, what code can I drop into my theme’s functions.php file to get the same net effect?
I have a dual-goal:
1. Don’t modify plugins to stay in sync with changes.
2. Restrict (allow) each role to the necessary set of capabilities provided by core WP and by each plugin
Perhaps the theme-based approach via functions.php might be a reasonable approach. From your example code, is all that “droppable” into functions.php ?
Thank you for making our lives simple and easy…. i liked this plugin and would love to use it on my website.
Most excellent plug-in Justin.
Just ran it through its paces and not only was it easy to set-up, but the action/alert items right after activation were helpful reminders.
Quick question– I’m also utilizing the Calendar plug-in. It has a feature that offers the admin to designate which lowest user rating has access to the calendar.
After creating a role via Members, it was not recognized via Members.
I’d like ultimately to offer editing of the calendar items only, with no other posting/editing access to certain users.
I’m not sure after reading this article if this is something that can be set via your plug-in. Is it just too late on a Friday for me to have grok’d it, or can you point me in the right direction.
Thanks again for an Excellent plug-in offering. It’s already gone into my folder labeled “must-have-plugs”, and has also gone on my writing list of items to review in my blog.
Have a great weekend.
Michael
Ack:
After creating a role via Members, it was not recognized via Members.
I meant to say “…it (role) was not recognized by Calendar”
Like I said, too late on a Friday night.
Thanks again.
MacBoy — This is a tutorial for developers, not end users. What this post is about is making sure developers give users the tools to make the those types of changes via
functions.php.oliver — You’re welcome. I’m glad you like it.
Michael Langham — What’s happening there is that your plugin isn’t properly using the WordPress roles system. Ask your plugin author to use the global
$wp_rolesvariable or theWP_Rolesclass rather than assuming that everyone uses the default roles.Hi Justin, I am a newbie programming and I was wondering if you can help me or tell me how much would you charge. I need to create a role that has access only to some plugins.
Thanks for your time
Gabriel
Hi,thanks fot yoy MEMBER plugin!
Making private pages is a piece of cake now!
I do have 1 question tough: I want to make a detail (not private) page that can be updated by one user only (with specific role).
So I make a capability ‘edit_member1_page’. But this doesn’t work. Do you have any suggestions..? thank you very muc,
leen
Hello again Justin.
The ‘calendar plug-in’ author has responded with the following info with regard to your suggestion that they employ “$wp_roles variable or the WP_Roles class rather than assuming that everyone uses the default roles” in your above reply to me.
For perusal, should you or others enjoy, is the link to the forum post:
View topic – Is Update planned to utilize WordPress roles system? http://j.mp/6n5rY
OOpah.
Here was his response:
Kieran wrote:
Possibly. The next major version will see an improvement to the permissions system, whether it will integrate with roles or not is a different matter. The more API documentation is provided to me in this thread, the more likely it is – I only understand the default permissions in WordPress at this point, hence their use in the plugin.
I guess I should have actually posed the question to this thread as to
“Where might Tieren get more information regarding codex for his plug-in’s revision so as to include “$wp_roles variable or the WP_Roles class” per Justin’s suggestion.
I’ll do the legwork for him if for no other reason than to pay-it-forward.
Thanks in advance.
Michael
Thanks for walking through the capabilities of your plug-in. Frankly, I have a moderate amount of technical knowledge (probably just enough to get into trouble), but your direction was quite clear. I maintain a blog with about a dozen writers some of whom really create a mess. I plan on looking more closely at using your plug-in to prevent some recent nightmares.
Again a very great plug in. Thank you for sharing your great talent and knowledge with us.
It looks great but my concern is… what would your wordpress become? Would your scipts be overwritten by any new auto updates you may want to do? How do you agree those things
Hmmm…I can apply it for my new site and I really appreciate your time for sharing it with us. I have been reading your posts and it’s really amazing how you can help people like me. Thanks a lot.
Hi, I am just starting in this plugins development and I am getting a little desperate. So if anyone here knows how to add to the Members plugin the capability to choose an admin to be able only to change some of the plugins that are installed on the theme, please let me know and how much will it cost.
For example I want one of the admins to be able to manage the options of three different plugins but not all the plugins that I have installed.
BTW I forgot in my previous post but you can send me an email if you can help me with it.
Just wanted to thank you for this plugin. I am just sorry I am not a professional developer, and that other developers don’t follow what you suggest here, so that I could take more advantage of your plugin and have more flexibility. But still this has helped me in my blog a lot.
I plan on having a lot of members. I am wondering what each role permission does specifically. I really appreciate the plugin and I think it is very useful so far. I know what most of the role permissions do but some of the AOC_ permissions are unclear to me. Also, I just added a new member and he is not showing up on my public members list(siege community) but the one I added before has shown up. Thanks in advance for your help and please keep up the exceptional work.
Very superb! If only features like these could be added to the core of wordpress by awesome designers like you!
I’m trying to add custom capabilities to a plugin of mine to change the capability that gives access to the plugin options page and I ran into a couple of issues. First it doesn’t look like the “members_plugin_init” function exists in version 0.2 of the Members plugin? I checked for the “members_get_capabilities” function instead and that worked for me.
The other bigger issue was that even though I can give any role with the custom capability access to the options page, they can’t actually make any changes to the options unless they also have the “manage_options” capability.
From this ticket it looks like this is a known issue. Do you know of another way to do this, or was this meant to be more of a proof of concept then a functioning example?
If you look at that entire ticket, you’ll see that they rolled the
option_page_capability_*hook into 3.2 as a fix for this problem. You can see an example of it in action in the TwentyEleven theme.I was looking at the wrong diff on that ticket, thanks for pointing me in the right direction Justin, got it working perfectly now!