Register a Custom User Role With Limited Capabilities
Registers a new WordPress user role with a hand-picked set of capabilities, instead of assigning people to an existing role that grants either too much or too little access.
- Difficulty
- Intermediate
- Reading time
- ~1 min
- Where to add it
- A snippet manager plugin (e.g. WPCode, Code Snippets)
- Last updated
The Problem
WordPress ships with five default roles, and in practice most sites end up stretching one of them to fit people who don't quite match it — giving a content team member the Editor role because Author can't edit others' posts, even though Editor also grants access to appearance and plugin-adjacent screens they have no business touching. That gap between "what this person actually needs" and "the closest available default role" is exactly what leads to over-privileged accounts, which is one of the most common ways a single compromised account turns into a bigger incident than it needed to be. `add_role()` lets you define a role with exactly the capabilities a specific job needs — no more, no less — instead of picking the least-bad default.
The Code
add_action( 'init', 'devmubs_register_custom_role' );
function devmubs_register_custom_role() {
if ( get_role( 'content_editor' ) ) {
return;
}
add_role(
'content_editor',
__( 'Content Editor' ),
array(
'read' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_published_posts' => true,
'publish_posts' => true,
'upload_files' => true,
'moderate_comments' => true,
'manage_categories' => true,
'edit_pages' => false,
)
);
}How It Works
`get_role()` returns `null` if a role doesn't exist yet, so the guard at the top means `add_role()` only actually runs once — after the first page load that registers it, every subsequent request skips straight past. The capabilities array is the actual definition: setting `edit_others_posts` and `publish_posts` to `true` gives this role the same team-wide editing reach as WordPress's built-in Editor role, but explicitly setting `edit_pages` to `false` withholds the one capability Editor has that this role deliberately shouldn't — access to static Pages, which are often reserved for site structure rather than day-to-day content. Every capability not listed here defaults to not-granted, so the resulting role only has exactly the eleven capabilities spelled out, nothing inherited or implied from elsewhere.
Where To Add This
A snippet manager plugin (e.g. WPCode, Code Snippets). Role registration is safe to keep in a snippet manager since the guard above makes it a no-op after the first run — there's no real downside to it being trivially toggleable.
Warnings & Caveats
- `add_role()` only affects users assigned to it after the role is registered — existing users keep whatever role they already have until you manually change it from their profile screen.
- If you remove this snippet later, the role itself stays in the database — deleting the snippet doesn't delete the role. Call `remove_role( 'content_editor' )` once (from an admin screen or WP-CLI) if you actually want it gone.
- Always back up your site before adding custom code.