1

Im trying to only show a taxonomy for the editor and administrator but I haven't found a solution on SO or here. The closest thing I was able to find was How do I remove a taxonomy from Wordpress? on SO. What is the proper way to only allow the taxonomy for the editor and administrator?

// remove from everyone that isn't admin or editor
function taxonomy_for_admin_and_editor_only() {
   if ( !current_user_can( 'administrator' ) || !current_user_can( 'editor' ) ) {
       register_taxonomy( 'foobar', array() );
   }
}
add_action( 'init' , 'taxonomy_for_admin_and_editor_only' );

I've tried add_action( 'admin' , 'taxonomy_for_admin_and_editor_only' ); with no luck either.

3 Answers 3

8

When registering your taxonomy you can pass an argument called capabilities. Simply passing capabiities that only admins and editors have.

$args = array(
    'capabilities' => array( 'manage_options', 'edit_posts' )
);
register_taxonomy( 'foobar', 'post', $args ); 

https://codex.wordpress.org/Roles_and_Capabilities#Editor

5
  • 1
    While my answer explains why the code in the question isn't functioning, this answer is the proper way to do it
    – Tom J Nowell
    Nov 8, 2015 at 0:57
  • 2
    Awesome. Just to clarify in the array you need to pass one for administrator and one for the editor?
    – user9447
    Nov 8, 2015 at 3:16
  • @Darth_Vader correct. you can pass any number of capabilities into the array. So just ensure you have at least one capability for each role you wish to have access. Nov 8, 2015 at 14:11
  • I think I found the solution and added it as answer for the next person. I marked this as the accepted answer since it was what I needed for a solution.
    – user9447
    Nov 8, 2015 at 20:51
  • For some reason, this doesn't work for me Jun 30, 2017 at 8:57
4

I never played with roles before so this was a fun learning experience. I'm leaving this because I've spent a lot of time researching this area and this might help the next person. I know my question is in regards to the taxonomy but I was confused with the issue so I wanted to test from a CPT level. The correct hook was admin_init however it was still removing the taxonomy from the administrator and editor and I did not want that.

Before the answer I did run across "Possible to hide Custom Post Type UI/Menu from specific User Roles?" but when I use a function like:

// hide from Contributors
function no_see_from_contributors() {
    if ( current_user_can( 'contributor' ) ) :
        remove_menu_page( 'edit.php' ); // Posts
        remove_menu_page( 'tools.php' ); // Tools
        remove_menu_page( 'edit-comments.php' ); // Comments
    endif;
}
add_action( 'admin_menu', 'no_see_from_contributors' );

create a test Contributor account, even though it is not visible from the menu a Contributor can still access this area by adding edit.php, tools.php or edit-comments.php in the URL. I'm going to test for a solution to prevent this and make an edit with a solution if I find one.

Further research after this led to "Restrict custom post type to only site administrator role" and "Remove Custom Post Type menu for non-administrator users" which were great reads. To learn more about capabilities you can visit Codex: register post type and scroll down to capability_type.

You can reference the codex for the Administrator and Editor on what roles to use in the array.

Final taxonomy:

function something_taxonomy() {
    $labels = array(
        'name'                       => _x( 'Taxonomies', 'Taxonomy General Name', 'theme' ),
        'singular_name'              => _x( 'Taxonomy', 'Taxonomy Singular Name', 'theme' ),
        'menu_name'                  => __( 'Taxonomy', 'theme' ),
        'all_items'                  => __( 'All Items', 'theme' ),
        'parent_item'                => __( 'Parent Item', 'theme' ),
        'parent_item_colon'          => __( 'Parent Item:', 'theme' ),
        'new_item_name'              => __( 'New Item Name', 'theme' ),
        'add_new_item'               => __( 'Add New Item', 'theme' ),
        'edit_item'                  => __( 'Edit Item', 'theme' ),
        'update_item'                => __( 'Update Item', 'theme' ),
        'view_item'                  => __( 'View Item', 'theme' ),
        'separate_items_with_commas' => __( 'Separate items with commas', 'theme' ),
        'add_or_remove_items'        => __( 'Add or remove items', 'theme' ),
        'choose_from_most_used'      => __( 'Choose from the most used', 'theme' ),
        'popular_items'              => __( 'Popular Items', 'theme' ),
        'search_items'               => __( 'Search Items', 'theme' ),
        'not_found'                  => __( 'Not Found', 'theme' ),
        'items_list'                 => __( 'Items list', 'theme' ),
        'items_list_navigation'      => __( 'Items list navigation', 'theme' ),
    );
    $capabilities = array(
        'edit_post'          => 'edit_pages',
        'read_post'          => 'edit_pages',
        'delete_post'        => 'edit_pages',
        'edit_posts'         => 'edit_pages',
        'edit_others_posts'  => 'edit_pages',
        'delete_posts'       => 'edit_pages',
        'publish_posts'      => 'edit_pages',
        'read_private_posts' => 'edit_pages'
    );
    $args = array(
        'labels'                     => $labels,
        'hierarchical'               => true,
        'public'                     => true,
        'show_ui'                    => true,
        'show_admin_column'          => true,
        'show_in_nav_menus'          => true,
        'show_tagcloud'              => true,
        'capabilities'               => $capabilities,
    );
    register_taxonomy( 'taxonomy_key', array( 'post', 'foo_key', 'bar_key' ), $args );
}
add_action( 'init', 'something_taxonomy', 0 );

What I used to remove the meta box from Contributors:

if ( is_admin() ) {
    function remove_metabox_for_non_admin_and_editor() {
        if ( current_user_can( 'contributor' ) || current_user_can( 'subscriber' ) ) {
            remove_meta_box( 'tagsdiv-foo_key_tag', 'foo_key', 'normal' );
            remove_meta_box( 'categorydiv', 'foo_key', 'normal' );
            remove_meta_box( 'foo_keyimagediv', 'foo_key', 'normal' );
            remove_meta_box( 'authordiv', 'foo_key', 'normal' );
            remove_meta_box( 'trackbacksdiv', 'foo_key', 'normal' );
            remove_meta_box( 'commentstatusdiv', 'foo_key', 'normal' );
            remove_meta_box( 'foo_keycustom', 'foo_key', 'normal' );
            remove_meta_box( 'commentstatusdiv', 'foo_key', 'normal' );
            remove_meta_box( 'commentsdiv', 'foo_key', 'normal' );
            remove_meta_box( 'revisionsdiv', 'foo_key', 'normal' );
            remove_meta_box( 'authordiv', 'foo_key', 'normal' );
            remove_meta_box( 'slugdiv', 'foo_key', 'normal' );
            remove_meta_box( 'taxonomy_keydiv', 'foo_key', 'normal' );
            // remove pages
            remove_menu_page( 'edit-comments.php' );
            remove_menu_page( 'edit.php' );
            remove_menu_page( 'tools.php' );
        }
    }
    add_action( 'admin_menu', 'remove_metabox_for_non_admin_and_editor' );
}

To find what the $id is for the custom meta box I used Chrome's inspect element to find the id it was creating. I chose admin_menu instead of admin_init after reading "What Wordpress hook fires first admin_init or admin_menu"

1

You want to use the admin_init hook:

add_action( 'admin_init' , 'taxonomy_for_admin_and_editor_only' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.