Customize user roles
The default WordPress roles and capabilities may be insufficient for the needs of some sites. A collection of helper functions are available in vip-go-mu-plugins for creating new roles or modifying existing roles. VIP recommends using these helper functions rather than the traditional methods to ensure that the code works as expected on the WordPress VIP platform.
- The VIP helper functions should be added with the
admin_init
hook. - Custom changes that are made to roles and capabilities will trigger a database update. Because of this, ensure that the helper functions only run when the role definitions need to change. One approach is to use a version value stored in the options table to check for changes. This approach is demonstrated in the code examples below.
- For sites with a high amount of traffic—or a site with many concurrently active editors—it is possible for changes to roles and capabilities to trigger a sudden spike of multiple identical database updates that can lead to performance issues. To prevent these issues, VIP recommends triggering the update with an added admin button on a special settings page, or to create a custom CLI command.
- If more than one plugin on a site adds or customizes roles, each plugin should have a separate option.
Add a capability to an existing user role
By default WordPress has six pre-defined roles: Super Admin (only on WordPress multisite), Administrator, Editor, Author, Contributor and Subscriber. Each role is allowed to perform a set of tasks called Capabilities.
The unfiltered_html
capability allows a user to post HTML markup or even JavaScript code in pages, posts, comments and widgets. On WordPress single sites the Administrator role has this capability by default. But on WordPress multisites, only the Super Admin has this capability.
This example demonstrates how to add the unfiltered_html
capability to the Administrator, Editor, and Author roles using the wpcom_vip_merge_role_caps()
function:
/**
* Run at priority 9 to beat the kses_init callback
* @see https://github.com/WordPress/WordPress/blob/f54720e6e55d6f556a5e207f57515a024c439a6d/wp-includes/default-filters.php#L581
*/
add_action( 'init', 'give_admins_unfiltered_html', 9 );
function give_admins_unfiltered_html() {
// Make no changes for single-site installs
if ( ! is_multisite() ) {
return;
}
// Determine if current user has enough cap to be considered 'admin'
$is_admin = current_user_can( 'manage_options' );
/**
* Default WP strictly prevents `unfiltered_html` cap for non-super-admins
* @see https://github.com/WordPress/WordPress/blob/f54720e6e55d6f556a5e207f57515a024c439a6d/wp-includes/capabilities.php#L596
* Restore cap only for users who have `manage_options`.
*
* Using anon function for ease of `use` so that the cap check
* is not performed within the callback, avoing an infinite loop.
*/
add_filter( 'map_meta_cap', function ( $caps, $cap, $user_id, $args ) use ( $is_admin ) {
if ( 'unfiltered_html' === $cap && $is_admin ) {
$caps = array( 'unfiltered_html' );
}
return $caps;
}, 1, 4 );
}
Create and define a new user role
In addition to the user roles that are pre-defined in WordPress, custom user roles can be added with their own unique set of capabilities.
In this example, a new role for a Reviewer is created and defined using the wpcom_vip_add_role()
function:
add_action(
'admin_init',
function() {
$ver = 42; // Incrementally update each time this code is changed.
// Check if this has been run already.
if ( $ver <= get_option( 'myplugin_roles_version' ) ) {
return;
}
// Add a Reviewer role.
wpcom_vip_add_role(
'reviewer',
'Reviewer',
array(
'read' => true,
'edit_posts' => true,
'edit_others_posts' => true,
'edit_private_posts' => true,
'edit_published_posts' => true,
'read_private_posts' => true,
'edit_pages' => true,
'edit_others_pages' => true,
'edit_private_pages' => true,
'edit_published_pages' => true,
'read_private_pages' => true,
)
);
// Update the version to prevent this running again.
update_option( 'myplugin_roles_version', $ver );
}
);
Modify multiple roles and capabilities
Several VIP helper methods are available for creating new roles and modifying capabilities for existing roles.
This example code demonstrates multiple VIP helper methods being used to modify user roles and their capabilities. The example code includes a version value stored in the options table to check for changes and ensure that the helper functions only run when the role definitions need to change:
add_action(
'admin_init',
function() {
$ver = 43; // Incrementally update each time this code is changed.
// Check if this has been run already.
if ( $ver <= get_option( 'myplugin_roles_version' ) ) {
return;
}
// Add new role.
wpcom_vip_add_role( 'reader', 'Reader', array( 'read' => true ) );
// Remove publish_posts cap from authors.
wpcom_vip_merge_role_caps( 'author', array( 'publish_posts' => false ) );
// Duplicate an existing role and modify some caps.
wpcom_vip_duplicate_role(
'administrator',
'station-administrator',
'Station Administrator',
array( 'manage_categories' => false )
);
// Add custom cap to a role.
wpcom_vip_add_role_caps( 'administrator', array( 'my-custom-cap' ) );
// Remove cap from a role.
wpcom_vip_remove_role_caps( 'author', array( 'publish_posts' ) );
// Update the version to prevent this running again.
update_option( 'myplugin_roles_version', $ver );
}
);
Last updated: April 07, 2025