How to Add Custom User Roles and Capabilities in WordPress

WordPress user roles and capabilities system controls who accesses what functionality. Beyond default roles (Administrator, Editor, Author), custom roles enable precise permission management for clients, contributors, and specialized users. This comprehensive guide teaches role creation, capability assignment, conditional content display, and advanced permission management for granular WordPress access control.

Understanding Roles vs Capabilities

Roles: Predefined permission sets assigned to users.

Capabilities: Specific permissions (edit_posts, publish_pages, manage_options).

Relationship: Roles contain multiple capabilities. Users assigned roles inherit those capabilities.

Example: Editor role includes edit_posts, publish_posts, edit_pages, but excludes manage_options.

Default WordPress Roles

Super Admin (Multisite only):

  • Network-level control
  • All capabilities across all sites

Administrator:

  • Complete site control
  • User management
  • Plugin/theme installation
  • Settings modification

Editor:

  • Manage and publish all posts
  • Moderate comments
  • Manage categories/tags

Author:

  • Write and publish own posts
  • Upload files
  • Cannot edit others’ posts

Contributor:

  • Write posts (cannot publish)
  • Edit own unpublished posts
  • No media upload

Subscriber:

  • Read content
  • Manage own profile
  • No posting capabilities

Creating Custom User Roles

Basic Role Creation:

function dprt_add_custom_role() {
    add_role(
        'client',                    // Role slug
        'Client',                    // Display name
        array(
            'read' => true,          // Capability
            'edit_posts' => false,
            'delete_posts' => false,
        )
    );
}
add_action('init', 'dprt_add_custom_role');

Run once: Use plugin activation hook or run manually then remove code.

Plugin Activation Hook:

register_activation_hook(__FILE__, 'dprt_add_custom_role');

Custom Role with Specific Capabilities

Content Manager Role:

function dprt_add_content_manager_role() {
    add_role('content_manager', 'Content Manager', array(
        // Basic capabilities
        'read' => true,

        // Post capabilities
        'edit_posts' => true,
        'edit_published_posts' => true,
        'publish_posts' => true,
        'delete_posts' => true,
        'delete_published_posts' => true,

        // Page capabilities
        'edit_pages' => true,
        'edit_published_pages' => true,
        'publish_pages' => true,
        'delete_pages' => true,

        // Media
        'upload_files' => true,

        // Comments
        'moderate_comments' => true,

        // Categories/Tags
        'manage_categories' => true,

        // Excluded capabilities
        'manage_options' => false,
        'edit_theme_options' => false,
        'install_plugins' => false,
        'activate_plugins' => false,
    ));
}
register_activation_hook(__FILE__, 'dprt_add_content_manager_role');

Adding Capabilities to Existing Roles

Add Capability to Role:

function dprt_add_capabilities_to_editor() {
    $role = get_role('editor');
    $role->add_cap('edit_theme_options');  // Access Appearance menu
    $role->add_cap('manage_options');      // Access Settings
}
add_action('admin_init', 'dprt_add_capabilities_to_editor');

Run once then remove to avoid adding capability repeatedly.

Removing Capabilities

function dprt_remove_capability() {
    $role = get_role('author');
    $role->remove_cap('publish_posts');  // Authors can't publish, only draft
}
add_action('admin_init', 'dprt_remove_capability');

Custom Post Type Capabilities

CPT with Custom Capabilities:

register_post_type('portfolio', array(
    'capability_type' => array('portfolio_item', 'portfolio_items'),
    'map_meta_cap' => true,
    // ... other args
));

Generates capabilities:

  • edit_portfolio_item
  • edit_portfolio_items
  • edit_published_portfolio_items
  • publish_portfolio_items
  • read_private_portfolio_items
  • delete_portfolio_items
  • etc.

Assign CPT Capabilities to Role:

function dprt_add_portfolio_caps_to_editor() {
    $role = get_role('editor');

    $caps = array(
        'edit_portfolio_item',
        'edit_portfolio_items',
        'edit_others_portfolio_items',
        'publish_portfolio_items',
        'read_private_portfolio_items',
        'delete_portfolio_items',
        'delete_private_portfolio_items',
        'delete_published_portfolio_items',
        'delete_others_portfolio_items',
        'edit_private_portfolio_items',
        'edit_published_portfolio_items',
    );

    foreach ($caps as $cap) {
        $role->add_cap($cap);
    }
}
add_action('admin_init', 'dprt_add_portfolio_caps_to_editor');

Removing Custom Roles

function dprt_remove_custom_role() {
    remove_role('client');
}
register_deactivation_hook(__FILE__, 'dprt_remove_custom_role');

Checking User Capabilities

Check if User Can:

if (current_user_can('manage_options')) {
    // User is administrator or has manage_options capability
    echo 'You have admin access';
}

if (current_user_can('edit_posts')) {
    echo 'You can edit posts';
}

Check Specific User:

$user = get_userdata($user_id);
if ($user && $user->has_cap('publish_posts')) {
    // User can publish posts
}

Conditional Content Display

Show Content Based on Role:

// Show admin-only content
if (current_user_can('administrator')) {
    echo '<div class="admin-notice">Admin-only message</div>';
}

// Show for multiple roles
if (current_user_can('edit_posts') || current_user_can('edit_pages')) {
    echo '<p>You can edit content</p>';
}

Shortcode for Role-Based Content:

function dprt_role_content_shortcode($atts, $content = null) {
    $atts = shortcode_atts(array(
        'role' => 'administrator',
    ), $atts);

    if (current_user_can($atts['role'])) {
        return do_shortcode($content);
    }

    return '';
}
add_shortcode('role_content', 'dprt_role_content_shortcode');

// Usage: [role_content role="editor"]Content for editors only[/role_content]

Admin Menu Restrictions

Hide Menu Items by Role:

function dprt_remove_menus() {
    // For non-administrators
    if (!current_user_can('administrator')) {
        remove_menu_page('tools.php');        // Tools
        remove_menu_page('plugins.php');      // Plugins
        remove_menu_page('themes.php');       // Appearance
        remove_menu_page('users.php');        // Users
    }

    // For editors (more restrictive)
    if (current_user_can('editor')) {
        remove_menu_page('options-general.php'); // Settings
    }
}
add_action('admin_menu', 'dprt_remove_menus', 999);

Dashboard Widget Restrictions

function dprt_remove_dashboard_widgets() {
    if (!current_user_can('administrator')) {
        remove_meta_box('dashboard_primary', 'dashboard', 'side');  // WordPress News
        remove_meta_box('dashboard_quick_press', 'dashboard', 'side'); // Quick Draft
    }
}
add_action('wp_dashboard_setup', 'dprt_remove_dashboard_widgets');

Custom Capabilities for Plugins

Create Plugin-Specific Capability:

function dprt_add_plugin_capability() {
    $admin = get_role('administrator');
    $admin->add_cap('manage_custom_plugin');

    $editor = get_role('editor');
    $editor->add_cap('use_custom_plugin');  // Limited access
}
register_activation_hook(__FILE__, 'dprt_add_plugin_capability');

// Check capability before showing plugin features
if (current_user_can('manage_custom_plugin')) {
    // Show advanced plugin settings
}

Role Management Plugins

Members Plugin:

  • GUI for role/capability management
  • Clone existing roles
  • Create custom capabilities
  • User-friendly interface

User Role Editor:

  • Edit role capabilities visually
  • Assign multiple roles to users
  • Capability filtering

PublishPress Capabilities:

  • Role duplication
  • Capability management
  • Custom post type integration

Advanced: Multiple Roles per User

WordPress doesn’t natively support multiple roles well, but:

function dprt_add_secondary_role($user_id, $role) {
    $user = get_userdata($user_id);
    $user->add_role($role);  // Adds role without removing existing
}

// Usage
dprt_add_secondary_role(5, 'editor');  // User 5 now has their original role + editor

Check Any of Multiple Roles:

function dprt_user_has_role($user_id, $roles) {
    $user = get_userdata($user_id);
    if (!$user) return false;

    foreach ($roles as $role) {
        if (in_array($role, (array) $user->roles)) {
            return true;
        }
    }
    return false;
}

// Usage
if (dprt_user_has_role($user_id, array('editor', 'administrator'))) {
    // User is editor OR administrator
}

Security Best Practices

Principle of Least Privilege: Grant minimum necessary capabilities.

Avoid Capability Checks by Role Name:

// BAD
if (in_array('administrator', $user->roles)) { }

// GOOD
if (current_user_can('manage_options')) { }

Capability checks are more flexible and future-proof.

Escape Output:

// When displaying user-submitted content based on roles
if (current_user_can('edit_posts')) {
    echo '<p>' . esc_html($user_content) . '</p>';
}

Debugging Roles and Capabilities

View User Capabilities:

function dprt_show_user_capabilities() {
    $user = wp_get_current_user();
    echo '<pre>';
    print_r($user->allcaps);  // All capabilities
    print_r($user->roles);     // Assigned roles
    echo '</pre>';
}
add_action('admin_notices', 'dprt_show_user_capabilities');

List All Roles:

global $wp_roles;
$all_roles = $wp_roles->roles;
print_r($all_roles);

Programmatic Role Assignment

Assign Role to User on Registration:

function dprt_set_default_user_role($user_id) {
    $user = get_userdata($user_id);
    $user->set_role('client');  // Change from default 'subscriber'
}
add_action('user_register', 'dprt_set_default_user_role');

Change Role Based on Conditions:

function dprt_upgrade_user_role($user_id) {
    // Example: Upgrade to author after 10 published comments
    $comment_count = get_comments(array(
        'user_id' => $user_id,
        'status' => 'approve',
        'count' => true
    ));

    if ($comment_count >= 10) {
        $user = get_userdata($user_id);
        $user->set_role('author');
    }
}

WooCommerce Custom Roles

Customer Role Modifications:

function dprt_modify_customer_role() {
    $customer = get_role('customer');
    $customer->add_cap('read');
    $customer->add_cap('view_order_history');  // Custom capability
}
add_action('init', 'dprt_modify_customer_role');

Conclusion

WordPress custom user roles and capabilities enable precise permission management beyond default role limitations. Create custom roles with add_role(), assign specific capabilities via add_cap(), check permissions using current_user_can(), and implement role-based content visibility. Programmatic role management provides granular access control for clients, contributors, and specialized users, ensuring security through least-privilege principles while maintaining workflow flexibility.

  1. WordPress Roles and Capabilities
  2. add_role() Reference
  3. current_user_can() Reference
  4. Members Plugin
  5. User Role Editor

Call to Action

User management configurations need protection. Backup Copilot Pro safeguards your WordPress user roles and permissions. Protect your access control setup—start your free 30-day trial today!