Can’t create new CPTs when menu hidden

I am adding a large number of custom post types and taxonomies so it is often visually clearer if I DO NOT have them all added to the admin menu’s top level. Instead I would prefer to add them under an appropriate sub-menu. I have done that without too much effort with this two step approach:

  1. Hiding CPT using the ‘show_ui’ property when registering the CPT
  2. Adding them back in using the add_submenu_page() call

For instance, here’s an example of the the add_submenu_page call for a CPT called “companies”:

Read More
add_submenu_page (LG_ADMIN_MENU,"Companies","Companies","manage_options",'edit.php?post_type=companies');

By taking these two steps I can now view the CPT, I can modify existing attributes, I can even delete a record but what I can’t do is add a record. When I click on the “Add New” button it comes back with a white screen that only says “Invalid post type”.

Now if I simply turn on the normal top-level menu (leaving all other settings alone), I get the menu now showing up both as a submenu (from my add_submenu_page call) and as a top-level menu (because I’ve turned that back on with “show_ui”. I can then add new items with no problem.

Related posts

Leave a Reply

1 comment

  1. That’s because at the very first lines of/wp-admin/post-new.php we have this:

    if ( !isset($_GET['post_type']) )
        $post_type = 'post';
    elseif ( in_array( $_GET['post_type'], get_post_types( array('show_ui' => true ) ) ) )
        $post_type = $_GET['post_type'];
    else
        wp_die( __('Invalid post type') );
    

    You are not passing that 'show_ui' => true condition.

    Time to get creative 🙂

    add_action( 'admin_menu', 'so_13255525_admin_menu' );
    
    function so_13255525_admin_menu() 
    {
        global $submenu;
    
        $submenu['index.php'][25] = $submenu['edit.php?post_type=portfolio'][5];
        $submenu['index.php'][30] = $submenu['edit.php?post_type=portfolio'][10];
    
        remove_menu_page( 'edit.php?post_type=portfolio' ); 
    }
    

    Results in:
    manipulation of $submenu global


    The show_ui is set to true. You’ll have to adapt this to suit your needs.

    Use this to inspect that global:

    add_action( 'admin_notices', 'so_13255525_admin_notice' );
    
    function so_13255525_admin_notice() 
    {
        if( !current_user_can( 'delete_plugins' ) )
            return;
        global $submenu;
        echo '<pre>' . print_r( $submenu, true ) . '</pre>';
    }