4

I'm currently working on a plugin that creates a custom post type. The issue I'm strugging with at the moment is that the custom post type is created fine, but when I go to add a new post I receive an "Invalid Post Type" error.

The ui is hidden and I'm trying to link to it from add_submenu_page. I need assistance for how to properly link it.

Here is what I have in the submenu declaration:

add_submenu_page( 'restaurant-orders', 'Menu Management', 'Menu Management', 'manage_options', 'edit.php?post_type=menu-item');

My post type:

function restaurant_menu_items() {

    $labels = array(
        'name' => __('Restaurant Menu Items', 'post type general name'),
        'singular_name' => __('Restaurant Menu Item', 'post type singular name'),
        'add_new' => __('Add New', 'product page'),
        'add_new_item' => __('Add New Menu Item'),
        'edit_item' => __('Edit Menu Item'),
        'new_item' => __('New Menu Item'),
        'view_item' => __('View Menu Item'),
        'search_items' => __('Search Menu Items'),
        'not_found' =>  __('Nothing found'),
        'not_found_in_trash' => __('Nothing found in Trash'),
        'parent_item_colon' => ''
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => false,
        'query_var' => true,
        'menu_icon' => get_stylesheet_directory_uri() . '/article16.png',
        'rewrite' => true,
        'capability_type' => 'post',
        'hierarchical' => false,
        'menu_position' => null,
        'supports' => array('title','editor','thumbnail'),
      ); 

    register_post_type( 'menu-item' , $args );
}

I can add a new post if I show the ui and do it the conventional way. However I do not want it this way, the post menu has to be under the plugin menu.

Thanks!

3 Answers 3

4

Magic here is:

'show_ui' => true,
'show_in_menu' => 'plugins.php',

Try this:

function restaurant_menu_items() {

    $labels = array(
        'name' => __('Restaurant Menu Items', 'post type general name'),
        'singular_name' => __('Restaurant Menu Item', 'post type singular name'),
        'add_new' => __('Add New', 'product page'),
        'add_new_item' => __('Add New Menu Item'),
        'edit_item' => __('Edit Menu Item'),
        'new_item' => __('New Menu Item'),
        'view_item' => __('View Menu Item'),
        'search_items' => __('Search Menu Items'),
        'not_found' =>  __('Nothing found'),
        'not_found_in_trash' => __('Nothing found in Trash'),
        'parent_item_colon' => ''
    );

    $args = array(
        'labels' => $labels,
        'public' => true,
        'publicly_queryable' => true,
        'show_ui' => true,
        'show_in_menu' => 'plugins.php',
        'query_var' => true,
        'menu_icon' => get_stylesheet_directory_uri() . '/article16.png',
        'rewrite' => true,
        'capability_type' => 'post',
        'hierarchical' => false,
        'menu_position' => null,
        'supports' => array('title','editor','thumbnail'),
      ); 

    register_post_type( 'menu-item' , $args );
}
7
3

As @ÜnsalKorkmaz already pointed out in his solution, one needs to use show_in_menu. I'm trying to explain what the problem with NULL or FALSE values is, when you're registering a custom post type or a custom taxonomy: There're defaults that you have to know... or have to know how to get enough feedback to understand what happens.

Inspect core

Take a look at register_post_type() internals. In the following example, which is taken from that API function, you'll see what happens.

// If not set, default to the setting for public.
if ( null === $args->show_ui )
    $args->show_ui = $args->public;

// If not set, default to the setting for show_ui.
if ( null === $args->show_in_menu || ! $args->show_ui )
    $args->show_in_menu = $args->show_ui;

Conclusions you can make after reading core internals

Most core functions have a default value that makes work even if you don't specify every value. And some of those parameters have a lower priority as others. You can see that with the public argument that will have a default only if show_ui was not defined.

How to gather enough feedback?

Most core functions have a hook to intercept the arguments and that runs before the actual task as well as another one that runs immediately afterwards. In this situation the later hook looks like this:

do_action( 'registered_post_type', $post_type, $args );

So you make yourself a little…

…plugin that helps you doing live debugging

This will now output/dump the full set of arguments, after core has thrown in its defaults. From my own experience: This is a massive helper as you can monitor every single change without getting down the rabbit hole and making your hands dirty in core. Enjoy.

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (#89066) Debug Register Post Type Args
 */
add_action( 'registered_post_type', 'wpse89066_debug_cpt_args', 10, 2 );
function wpse89066_debug_cpt_args( $post_type, $args )
{
    printf( '<h1>%s</h1>', $post_type );
    var_dump( $args );
}

Full Plugin

You can grab the full version of this plugin over here at GitHub as Gist.

3
  • Small hint. The Plugin Debug Objects (currently only the git version, is not released in sv n of wp.org) list the arguments for custom post types, same topic.
    – bueltge
    Commented Mar 2, 2013 at 13:39
  • @bueltge Nice. Didn't know about this one. Should be a separate answer. I'm now reverting your edit as my plugin simply isn't yours and the output you added would raise the wrong expectations :)
    – kaiser
    Commented Mar 2, 2013 at 14:48
  • Ok, I have think, it is the same output, only the change on style.
    – bueltge
    Commented Mar 2, 2013 at 15:27
2

The helper plugin for developer Debug Objects list the arguments of custom post types, easy to use. But for this output part use the current development version on github, she have more features.

Example output of arguments to custom post type. enter image description here

1
  • Nice plugin +1 for this .
    – kaiser
    Commented Mar 2, 2013 at 15:31

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.