Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WordPress: Disable "Add New" on Custom Post Type

Tags:

wordpress

Is there any way to disable the option of adding a new post under a Custom Post Type in WordPress (3.0)? I've looked into labels and arguments but can't find anything that would resemble such a feature.

like image 388
Staffan Estberg Avatar asked Jul 13 '10 08:07

Staffan Estberg


3 Answers

There is a meta capability create_posts that is documented here and is used by WordPress to check before inserting the various 'Add New' buttons and links. In your custom post type declaration, add capabilities (not to be confused with cap) and then set it to false as below.

register_post_type( 'custom_post_type_name', array(
  'capability_type' => 'post',
  'capabilities' => array(
    'create_posts' => false, // Removes support for the "Add New" function ( use 'do_not_allow' instead of false for multisite set ups )
  ),
  'map_meta_cap' => true, // Set to `false`, if users are not allowed to edit/delete existing posts
));

You'll probably want to set map_meta_cap to true as well. Without it, you won't be able to access the posts' editing pages anymore.

like image 71
Seamus Leahy Avatar answered Nov 18 '22 19:11

Seamus Leahy


The combinations of the solutions above work in hiding the links (although someone could quite easily type the URL in directly.

The solution mentioned @3pepe3 relies on get_post_type() which will only work if there is already a post in the listing. If there are no posts, the function will not return anything, and the "Add New" link will be available. An alternative method:

function disable_new_posts() {
    // Hide sidebar link
    global $submenu;
    unset($submenu['edit.php?post_type=CUSTOM_POST_TYPE'][10]);

    // Hide link on listing page
    if (isset($_GET['post_type']) && $_GET['post_type'] == 'CUSTOM_POST_TYPE') {
        echo '<style type="text/css">
        #favorite-actions, .add-new-h2, .tablenav { display:none; }
        </style>';
    }
}
add_action('admin_menu', 'disable_new_posts');

EDIT: To prevent direct access if someone types the URL in themselves: https://wordpress.stackexchange.com/a/58292/6003

like image 43
Kirk Beard Avatar answered Nov 18 '22 19:11

Kirk Beard


In wordpress and for all the post types there is the capability create_posts. This capability is used in several core files :

  1. wp-admin\edit-form-advanced.php
  2. wp-admin\edit.php
  3. wp-admin\includes\post.php
  4. wp-admin\menu.php
  5. wp-admin\post-new.php
  6. wp-admin\press-this.php
  7. wp-includes\admin-bar.php
  8. wp-includes\class-wp-xmlrpc-server.php
  9. wp-includes\post.php

So if you really want to disable this feautere you must do it per role and per post type. I use the great plugin "User Role Editor" to manage the capabilities per role.

But what about the capability create_posts? Well this capability is not mapped and also create_posts is equal to create_posts so we should fix this and map the capability per post type.

So you can add this piece of code in your functions.php and the you can manage this capability.

function fix_capability_create(){
    $post_types = get_post_types( array(),'objects' );
    foreach ( $post_types as $post_type ) {
        $cap = "create_".$post_type->name;
        $post_type->cap->create_posts = $cap;
        map_meta_cap( $cap, 1); 
    }
}
add_action( 'init', 'fix_capability_create',100);

So here we are not hiding or removing menu elements... here we are removing the capability for users (including xmlrpc requests).

The action was init and not admin_init or anything else because init at priority 100 prevents the display of "add new" on admin bar, sidebar, etc (in all the wp interface).

like image 7
3pepe3 Avatar answered Nov 18 '22 18:11

3pepe3