Select other roles as custom post authors

The question:

I created a custom post type (“Organization”), and I’ve also created a custom user role (“Representative”). Also, I’ve ensured that the Representative role has read/edit/create/publish post capabilities.

I then, programmatically, assigned a Representative as the “author” of the Organization.

When I am on the Organizations overview screen (WP Admin > Organizations), I see the proper representative in the “Author” column.

However, when editing the Organization, the “Author” dropdown only shows Admin/Editor/Contributors. It does not allow me to view/select Representatives as the author of an organization.

I’ve searched and cannot find the answer. Am I doing this wrong, or is there a way to hook into WP and have it recognize other roles?

Edit: Here is the Custom Post Type:

function cptui_register_my_cpts_organization_info() {

    /**
     * Post Type: Organizations.
     */

    $labels = [
        "name" => __( "Organizations", "hello-elementor-child" ),
        "singular_name" => __( "Organization", "hello-elementor-child" ),
        "menu_name" => __( "Organizations", "hello-elementor-child" ),
        "all_items" => __( "All Organizations", "hello-elementor-child" ),
        "add_new" => __( "Add New", "hello-elementor-child" ),
        "add_new_item" => __( "Add new Organization", "hello-elementor-child" ),
        "edit_item" => __( "Edit Organization", "hello-elementor-child" ),
        "new_item" => __( "New Organization", "hello-elementor-child" ),
        "view_item" => __( "View Organization", "hello-elementor-child" ),
        "view_items" => __( "View Organizations", "hello-elementor-child" ),
        "search_items" => __( "Search Organizations", "hello-elementor-child" ),
        "not_found" => __( "No Organizations found", "hello-elementor-child" ),
        "not_found_in_trash" => __( "No Organizations found in trash", "hello-elementor-child" ),
        "parent" => __( "Parent Organization:", "hello-elementor-child" ),
        "featured_image" => __( "Organization Logo", "hello-elementor-child" ),
        "set_featured_image" => __( "Upload Organization Logo", "hello-elementor-child" ),
        "remove_featured_image" => __( "Remove Organization Logo", "hello-elementor-child" ),
        "use_featured_image" => __( "Use as logo for this Organization", "hello-elementor-child" ),
        "archives" => __( "Organization archives", "hello-elementor-child" ),
        "insert_into_item" => __( "Insert into Organization", "hello-elementor-child" ),
        "uploaded_to_this_item" => __( "Upload to this Organization", "hello-elementor-child" ),
        "filter_items_list" => __( "Filter Organizations list", "hello-elementor-child" ),
        "items_list_navigation" => __( "Organizations list navigation", "hello-elementor-child" ),
        "items_list" => __( "Organizations list", "hello-elementor-child" ),
        "attributes" => __( "Organizations attributes", "hello-elementor-child" ),
        "name_admin_bar" => __( "Organization", "hello-elementor-child" ),
        "item_published" => __( "Organization published", "hello-elementor-child" ),
        "item_published_privately" => __( "Organization published privately.", "hello-elementor-child" ),
        "item_reverted_to_draft" => __( "Organization reverted to draft.", "hello-elementor-child" ),
        "item_scheduled" => __( "Organization scheduled", "hello-elementor-child" ),
        "item_updated" => __( "Organization updated.", "hello-elementor-child" ),
        "parent_item_colon" => __( "Parent Organization:", "hello-elementor-child" ),
    ];

    $args = [
        "label" => __( "Organizations", "hello-elementor-child" ),
        "labels" => $labels,
        "description" => "",
        "public" => true,
        "publicly_queryable" => true,
        "show_ui" => true,
        "show_in_rest" => true,
        "rest_base" => "",
        "rest_controller_class" => "WP_REST_Posts_Controller",
        "has_archive" => true,
        "show_in_menu" => true,
        "show_in_nav_menus" => true,
        "delete_with_user" => false,
        "exclude_from_search" => false,
        "capability_type" => "post",
        "map_meta_cap" => true,
        "hierarchical" => false,
        "rewrite" => [ "slug" => "org", "with_front" => true ],
        "query_var" => true,
        "menu_icon" => "dashicons-networking",
        "supports" => [ "title", "editor", "thumbnail", "custom-fields", "author" ],
        "taxonomies" => [ "organization_services" ],
        "show_in_graphql" => false,
    ];

    register_post_type( "organization_info", $args );
}

add_action( 'init', 'cptui_register_my_cpts_organization_info' );

Edit Furthermore, I ensure that the role “Representative” has a user level of at least 1:

Select other roles as custom post authors

After making these changes, however, I still did not see the Representative showing in the “Author” dropdown for this custom post type.

I even manually added wp_user_level and set it to 2 inside of wp_usermeta in the DB, but still didn’t work.

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

I’ve ensured that the Representative role has read/edit/create/publish
post capabilities

Okay, that’s good.

But did you also assign the level_<number> capability to the role, where the <number> is at least 1? If not, then at least the users in the role need to be manually assigned the level 1 or a greater level (2, 3, etc.).

And the reason is because the Author dropdown on the post editing screen will only include users having a level of at least 1 and the level is stored in a user metadata named wp_user_level in a non-Multisite install.

More specifically, the Author dropdown uses wp_dropdown_users() (if your post type uses the old/classic editor) or the GET /wp/v2/users endpoint in the REST API (if your post type uses Gutenberg, i.e. enabled in the REST API) with the who argument set to authors which then includes only those users having a user level of 1 or above. (see source on Trac)

So please ensure that the Representative role has the proper user level capability so that new users will automatically have the above metadata set to the correct value.

For existing users in that role, you could programmatically update their wp_user_level metadata (using update_user_meta()), or you could use a raw SQL to update that metadata, or if you have WP-CLI installed on your site, then you could easily update individual users using the wp user meta update command like so: wp user meta update 123 wp_user_level 1 (where 123 is the user ID).

UPDATE

In reply to your comment:

The meta field I created before was wp_user_level inside of the
usermeta table. However, this meta key has to include the WP table’s
prefix. So, if your wp table prefix is wp_12 (meaning, your usermeta
table is named wp_12_usermeta), then the wp_user_level meta key
must also have the prefix. So, once I set wp_12_user_level to 1,
it worked!

Yes, that is correct and sorry for not clarifying about the prefix.. 🙂

So the user level meta is named following this format: <blog prefix>user_level, where the blog prefix is in the form of <base prefix><site ID>_ or just <base prefix> (see the Multisite note in the next paragraph), and the base prefix defaults to the WordPress table prefix ($wpdb->prefix), e.g. wp_12_ in your case (note that the prefix includes the last _).

Therefore in a stock WordPress install where the table prefix defaults to wp_, the user level meta would be named wp_user_level; however, if Multisite was enabled, then the name (meta key) would be wp_2_user_level if the ID of the current (sub-)site is 2. The main site, though, always uses the format <table/base prefix>user_level, i.e. without the <site ID>_ part.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment