How to add a custom post type into the sub-menu of a custom menu

Yeah I know the title is a bit weird, but it describes the problem that I faced today. I started developing my first real plugin and I wanted to achieve the following:

  1. create an admin menu page, with function add_menu_page()  -> easy,
  2. add a sub-menu page called “settings”, with function add_submenu_page() -> easy,
  3. register a custom post type and put it under the menu from point 1. -> easy, but not for a beginner  🙂

Maybe a picture will help.

Main admin menu

“TTLM” is a menu page that I created, “settings” is the sub-menu page. I wanted to add a custom post type named “Teams” to be placed in between.

This is how I accomplished it:

// 1. when registering a custom post type set show_in_menu to false,
function ttlm_register_team_custom_type() {
	$labels = array(
		'name'               => _x( 'Teams', 'post type general name', 'your-plugin-textdomain' ),
		'singular_name'      => _x( 'Team', 'post type singular name', 'your-plugin-textdomain' ),
		'menu_name'          => _x( 'Teams', 'admin menu', 'your-plugin-textdomain' ),
		'name_admin_bar'     => _x( 'Team', 'add new on admin bar', 'your-plugin-textdomain' ),
		'add_new'            => _x( 'Add New', 'team', 'your-plugin-textdomain' ),
		'add_new_item'       => __( 'Add New Team', 'your-plugin-textdomain' ),
		'new_item'           => __( 'New Team', 'your-plugin-textdomain' ),
		'edit_item'          => __( 'Edit Team', 'your-plugin-textdomain' ),
		'view_item'          => __( 'View Team', 'your-plugin-textdomain' ),
		'all_items'          => __( 'All Teams', 'your-plugin-textdomain' ),
		'search_items'       => __( 'Search Teams', 'your-plugin-textdomain' ),
		'parent_item_colon'  => __( 'Parent Teams:', 'your-plugin-textdomain' ),
		'not_found'          => __( 'No teams found.', 'your-plugin-textdomain' ),
		'not_found_in_trash' => __( 'No teams found in Trash.', 'your-plugin-textdomain' )

	$args = array(
		'labels'             => $labels,
		'public'             => true,
		'publicly_queryable' => true,
		'show_ui'            => true,
		'show_in_menu'       => false, //<--- HERE
		'query_var'          => true,
		'rewrite'            => array( 'slug' => 'ttlm_team' ),
		'capability_type'    => 'post',
		'has_archive'        => true,
		'hierarchical'       => false,
		'menu_position'      => null,
		'supports'           => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'comments' )

	register_post_type( 'ttlm_team', $args );
add_action( 'init', 'ttlm_register_team_custom_type' );

// 2. when adding a sub-menu page set the callback function to NULL and
// set the menu_slug to the appropriate custom post type url 
// (in this case it's edit.php?post_type=ttlm_team)
add_submenu_page( 'ttlm', 'TTLM Teams', 'Teams', 
'manage_options', 'edit.php?post_type=ttlm_team', NULL );

So basically:

  1. when registering a custom post type set the ‘show_in_menu’ argument to false,
  2. when adding a sub-menu item set the callback function to NULL and the menu_slug to the custom post type, e.g. ‘edit.php?post_type=your_custom_post_type_name_goes_here’

I hope this helps and if you have any questions don’t hesitate to ask in the comments bellow.


  1. Can you please let me know, how to get that submenu( custom post type ) item to highlight when its active.


  2. Great post. You can also define the location for the post type in the show_in_menu like this:

    ‘show_in_menu’ => ‘edit.php?post_type=ttlm_team’,

  3. when happens when i register taxonomy to that sub-menu CPT? it isn’t appearing. only thing i found is

    add_action(‘admin_menu’, ‘my_admin_menu’);
    function my_admin_menu() {
    add_submenu_page(‘edit.php?post_type=parent_post’, ‘Title, ‘Title’, ‘manage_options’, ‘edit-tags.php?taxonomy=calendar_cat&post_type=parent_post’);

    `Title` will be appear along with the CPT and not as further sub of child cpt. Is it even possible of not?

    1. Hi,

      further nesting in WP admin menu is not possible (as far as I know) … I would advise that you use the normal “main” menu item with `add_menu_page` WP function call.

      Take care!

Leave a comment

Your email address will not be published. Required fields are marked *