show different admin menu to different user roles

The menu items are bound to capabilities. A good overview can be found here. For example, if you do not have the capability edit_posts the menu item “Posts” would not show up.

How are menu items bound to capabilites. Generally speaking: If you register a menu item using add_menu_page() or add_submenu_page() you have to assign a capability to tell WordPress what users can access this page and see it in the menu.

If you want to dig deeper into the capabilites, which are bound to the default menu items, you can browse the source code.

You can also use this little script, which gives you an overview of your current menu and the capabilites attached. It should be used for development reasons only and for sure, it can be improved, but you get the general idea:

add_action( 'in_admin_footer', function() {

    global $menu, $submenu;
    echo '<p>Menu:</p><table class="table widefat">';
    echo '<tr><th>Name</th><th>Slug</th><th>Capability</th>';
    foreach ( $menu as $key => $item ) {
        echo '<tr><td>' . esc_html( $item[0] ) . '</td><td>' . esc_html( $item[2] ) . '</td><td><td>' . esc_html( $item[1] ) . '</td><td></tr>';
    }
    echo '</table>';
    echo '<p>Submenu:</p><table class="table widefat">';
    echo '<tr><th>Name</th><th>Slug</th><th>Capability</th>';
    foreach ( $submenu as $index => $subsub ) {
        foreach ( $subsub as $key => $item ) {
            echo '<tr><td>' . esc_html( $item[0] ) . '</td><td>' . esc_html( $item[2] ) . '</td><td><td>' . esc_html( $item[1] ) . '</td><td></tr>';
        }

    }
    echo '</table>';
});

So, if you create a new user role, you can assign them capabilities and by those, you can decide, whether a specific user role should see the “Edit Post”-menu item or not. You can find a detailed instruction to add user roles and capabilities in the WordPress Codex.

If you want to remove a specific menu item, but you still want to grant the user the principal capability, you can use remove_menu_page(). Therefore you would need to know the slug of the menu item you want to remove. This example would remove the “Plugins” item from the menu:

add_action( 'admin_menu', function(){
    remove_menu_page( 'plugins.php' );
});