Hi I'm trying to define custom post type capabilities for staff contracts on an intranet site, so due to the sensitivity of the information this needs to have as best security as possible and simply hiding the menu links via jQuery or css isn't good enough.

Here's how I've defined the post type at the moment:

function user_contract_post_type(){
        'labels' => array(
        'name' => __('Contracts', 'intranet'),
        'singular_name' => __('Contract', 'intranet')
        'public' => true,
        'publicly_queryable' => true,
        'exclude_from_search' => true,
        'show_ui' => true,
        'menu_position' => 71,
        'query_var' => true,
        'has_archive' => false,
        'rewrite'   => array(
        'slug' => 'contracts',
        'with_front' => false,
        'feeds' => false
        'hierarchical' => false,
        'supports' => array(
        'capability_type' => 'contract',
        'capabilities' => array(
        'map_meta_cap' => true,
        'can_export' => true
add_action('init', 'user_contract_post_type');

Which is allowing me to edit the contracts as I can see the Contracts link in the admin main-menu and the Contracts edit screen, whereas other users can't, but I can't do anything else. All I can do is read and update an already published contract, and preview and submit new contracts for review.

Any help is much appeciated. Thanks!

1 Answer 1


You are probably going to want to look into mapping the meta caps. This will let you have a function that individually right before WordPress decides on whether or not to give access to certain functionalities.

With that, you can do a check for the level of user (say administrator), and only grant access to read and edit contracts if the user meets that level. You can even take it further to not only check for being an administrator, but also check if the user has a certain ID (or set of IDs).

add_action( 'map_meta_cap', 'my_meta_cap', 10, 4 );
function my_meta_cap( $caps, $cap, $user_id, $args ){

    if( current_user_can( 'administrator' ) ){
        return array( 'edit_contract' );

    return array();


You can also do cool things like check the author of the contract and such before granting access. You could make a custom rule that contract written by you can't be edited by anyone else, but you can edit anyone else's contract.

There are a few interesting references to learn more about this granular control. I found these while researching your question (in Google):

  • Cheers, I will give this a try and get to you when I know the outcome.
    – Ben
    Commented Nov 23, 2012 at 15:48

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.