How to set individual capabilities on a taxonomy? Or how to re-register an existing taxonomy?

The default taxonomy, category. By default, only those with the edit_posts capability can assign categories during post creation/editing.

I have a role with very limited capabilities. I want to let users in this role be able to assign categories during custom-post-type creation/editing, but I cannot give them the edit_posts capability and they should not be able to edit the taxonomy, only assign it.

Read More

How can I do this? Setting 'assign_terms' => 'read' is one option, but how can I set that value without having to re-register the taxonomy?

Or alternatively, how can I give my low-level role permission to assign the taxonomy?

Related posts

3 comments

  1. This should works

    add_action( 'init', 'register_category_again', 1 );
    
    function register_category_again() {
      $user = wp_get_current_user();
      if ( $user->roles[0] != 'your_custom_role' ) return;
      global $wp_taxonomies;
      unset( $wp_taxonomies['category'] );
      global $wp_rewrite;
      $rewrite = array(
        'hierarchical' => true,
        'slug' => get_option('category_base') ? get_option('category_base') : 'category',
        'with_front' => ! get_option('category_base') || $wp_rewrite->using_index_permalinks(),
        'ep_mask' => EP_CATEGORIES,
      );
      register_taxonomy( 'category', 'post', array(
        'hierarchical' => true,
        'query_var' => 'category_name',
        'rewrite' => $rewrite,
        'public' => true,
        'capabilities' => array(
          'manage_terms'=> 'manage_categories',
          'edit_terms'=> 'manage_categories',
          'delete_terms'=> 'manage_categories',
          'assign_terms' => 'read'
        ),
        'show_ui' => true,
        'show_admin_column' => true,
        '_builtin' => true,
      ) );
    }
    
  2. I just found this question and although it might work, I was not satisfied with the solution. There had to be a better way to do this, without registering the taxonomy again. And there is a better solution, I am now using in my CPT plugin.

    public function wpse_108219_set_taxonomy_caps( $taxonomy, $object_type, $args ) {
        global $wp_taxonomies;
    
        if ( 'category' == $taxonomy && 'cpt_item' == $object_type ) {
            $wp_taxonomies[ $taxonomy ]->cap->assign_terms = 'edit_cpt_items';
        }
    
    }
    
    add_filter( 'registered_taxonomy', 'wpse_108219_set_taxonomy_caps' ), 10, 3 );
    

    In this example, I set the assign_terms capability for the custom post type cpt_item to the custom capability edit_cpt_items which enables any user with this capability to assign categories to the CPT.

    I hope this cleaner solution also works for you.

  3. You could also filter core’s category args before the taxonomy is registered:

    <?php
    /*
     * Set the capabilities for the category taxonomy before it's registered.
     *
     * @param array  $args        Array of arguments for registering a taxonomy.
     * @param array  $object_type Array of names of object types for the taxonomy.
     * @param string $taxonomy    Taxonomy key.
     */
    function wpse_108219_register_taxonomy_args( $args, $taxonomy, $object_type ) {
    
        if ( 'category' === $taxonomy ) {
    
            $args['capabilities'] = array(
                'manage_terms' => 'manage_categories',
                'edit_terms'   => 'manage_categories',
                'delete_terms' => 'manage_categories',
                'assign_terms' => 'read',
            );
    
        }
    
        return $args;
    }
    
    add_filter( 'register_taxonomy_args', 'wpse_108219_register_taxonomy_args', 10, 3 );
    

Comments are closed.