4

We're configuring a new WordPress to use custom post types, and we want our editors to log in and only see only the custominzed post types, not the default 'post' post type. We've been able to remove 'post' from the Admin menu using this trick, but that still leaves the "+ New" Admin toolbar button, which contains a post option and defaults to creating a post. Is there an easy and safe way to remove post from the new toolbar button and/or hide the new toolbar button?

  • If you remove the posts related capabilities from the Editor role (or whichever you're using) these options shouldn't appear. – Jacob Peattie Feb 5 '18 at 3:38
13

You need to hook to 3 different action hooks to fully hide the default post type. However, a direct access to the default post by URL is still possible. So, let's get started.

The Side Menu

add_action( 'admin_menu', 'remove_default_post_type' );

function remove_default_post_type() {
    remove_menu_page( 'edit.php' );
}

The +New Post in Admin Bar

add_action( 'admin_bar_menu', 'remove_default_post_type_menu_bar', 999 );

function remove_default_post_type_menu_bar( $wp_admin_bar ) {
    $wp_admin_bar->remove_node( 'new-post' );
}

The Quick Draft Dashboard Widget

add_action( 'wp_dashboard_setup', 'remove_draft_widget', 999 );

function remove_draft_widget(){
    remove_meta_box( 'dashboard_quick_press', 'dashboard', 'side' );
}
  • This is the cleanest way, although the New button in the admin bar still points to post-new.php - can be disabled with some Javascript e.g. $(document).on('click', '#wp-admin-bar-new-content', function(){ return false }) – Mina Jul 27 '19 at 10:39
3

In principle it is possible to unregister already registered post types using unregister_post_type(). Unfortunately this is not possible for _builtin post types.

Alternatively it is possible to change the capabilities which are required to edit/create/delete/... posts for a specific post type. You could use the register_post_type_args filter to change the capabilities which are required for the default post post type. Setting all capabilities to false will result in nobody having access to the default post post type. WordPress is smart enough to automatically hide the navigation entries.

add_filter('register_post_type_args', function($args, $postType){
    if ($postType === 'post') {
        $args['capabilities'] = [
            'edit_post' => false,
            'read_post' => false,
            'delete_post' => false,
            'edit_posts' => false,
            'edit_others_posts' => false,
            'publish_posts' => false,
            'read' => false,
            'delete_posts' => false,
            'delete_private_posts' => false,
            'delete_published_posts' => false,
            'delete_others_posts' => false,
            'edit_private_posts' => false,
            'edit_published_posts' => false,
            'create_posts' => false,
        ];
    }

    return $args
}, 0, 2);
  • Thanks, I put this code into a function that was fired on the 'init' event, but it didn't seem to have any effect on my UI. Am I hooking the wrong event? – Paul Keister Feb 5 '18 at 17:48
  • That is too late. WordPress registers all _builtin post types at the init action but with an priority of 0. The code above is registering just a filter, you do not have to put it inside another action/filter, just write it directly into your themes functions.php for example. – Stefan Feb 5 '18 at 18:47
  • +1. The thing is it throws 3 notices. "Notice: Undefined offset: 0 in /var/www/html/wp-includes/capabilities.php on line 70". I couldn't get rid of them. – noway Nov 17 '19 at 11:37
0

Stefan's solution is great, but if you active debug you can see : Undefined offset: 0 in wp-includes/capabilities.php on line 62 plus there is a missing ; after return $args

Exhaustive code should be :

add_filter('register_post_type_args', function($args, $postType){
    if ($postType === 'post' && current_user_can( 'create_posts' ) && current_user_can( 'edit_post' ) ) {
        $args['capabilities'] = [
            'edit_post' => false,
            'read_post' => false,
            'delete_post' => false,
            'edit_posts' => false,
            'edit_others_posts' => false,
            'publish_posts' => false,
            'read' => false,
            'delete_posts' => false,
            'delete_private_posts' => false,
            'delete_published_posts' => false,
            'delete_others_posts' => false,
            'edit_private_posts' => false,
            'edit_published_posts' => false,
            'create_posts' => false,
        ];
    }
    return $args;
}, 0, 2);
  • current_user_can throws an error. It is not defined yet at this stage. – noway Nov 17 '19 at 11:59
0

An alternative, but similar solution to Stefan and Rafa's. This does not throw errors, and notice if you navigate directly to /wp-admin/edit.php you will not be able to view the list of posts (default post type), or edit them.

Note this code does not actually disable the default post type, i.e. existing post types will still be published and accessible via public URL. It effectively disables backend access to the default post type for all users.

function remove_default_post_type($args, $postType) {
    if ($postType === 'post') {
        $args['public']                = false;
        $args['show_ui']               = false;
        $args['show_in_menu']          = false;
        $args['show_in_admin_bar']     = false;
        $args['show_in_nav_menus']     = false;
        $args['can_export']            = false;
        $args['has_archive']           = false;
        $args['exclude_from_search']   = true;
        $args['publicly_queryable']    = false;
        $args['show_in_rest']          = false;
    }

    return $args;
}
add_filter('register_post_type_args', 'remove_default_post_type', 0, 2);

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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