How to let an Editor access widgets?

Editor role by default does not have access to ‘Appearance’ menu. Recently I came across one request where the client wanted the ‘Editor’ role to have access to ‘Widgets’ section. While this is easily achievable by giving edit_theme_options capability to editor user role, it shows all menu items under ‘Appearance’ and not just ‘Widgets’.

The crux was that the client only wanted ‘Widgets’ menu to be accessible and no other menu under ‘Appearance’. So here is how I decided to approach this problem statement:

  • Get all capabilities associated with editor role
  • Check if the editor role already has ‘edit_theme_options’ capability. If not then assign that capability
  • Get the current logged in user’s role
  • If the current logged in user is not ‘editor’ then return (simply don’t execute rest of the logic)
  • Now we know the user is editor – do the magic to hide all submenus under ‘Appearance’ except Widgets submenu.

Here is all the related code:

function update_editor_caps() {
    global $submenu;
    // gets the editor role    
    $roleObject = get_role( 'editor' );
    // gets all the roles associated with current logged in user
    $roles = wp_get_current_user()->roles;

    // Check if it is editor role
    if( !in_array( 'editor',$roles ) ){
        return;
    }
    
    // Now we are sure its editor role, give them edit_theme_options permission
    if( !$roleObject->has_cap( 'edit_theme_options' ) ) {
        $roleObject->add_cap( 'edit_theme_options' );
    }
  
    // Since we only want to give widgets permission, lets remove other menus under Themes
    if ( isset( $submenu[ 'themes.php' ] ) ) {
        foreach ( $submenu[ 'themes.php' ] as $index => $menu_item ) {
            foreach ($menu_item as $value) {
                if ( strpos( $value, 'customize' ) !== false || strpos( $value, 'nav-menu' ) !== false || strpos( $value, 'themes' ) !== false ) {
                    unset( $submenu[ 'themes.php' ][ $index ] );
                }
            }
        }
    }
}
add_action( 'admin_menu', 'update_editor_caps' );

Above will take care of ‘Appearance’ menu items in the dashboard. What about the ‘Customize’ menu that shows up on front end admin bar. We can simply remove the ‘Customize’ node from the front end admin bar using below snippet:

// We also need to remove Customize menu from the admin bar
function remove_customize_menu_bar( $wp_admin_bar ) {
    $wp_admin_bar->remove_node( 'customize' );
}
add_action( 'admin_bar_menu', 'remove_customize_menu_bar', 41 );

Final note: you need to place this code in your theme’s functions.php file. Do share in comments if this article proves helpful.

Leave a Reply