i want insert a dropdown menu with list of menus, that i've created in nav-menu.php, to post-admin...

For example, when i'm creating a post, i want insert a menu "Paul" in a post (only a post that i want) selecting a menu at right sidebar of Admin-Post.

I've copied the rows:

add_action( 'init', 'register_my_menus' );
function register_my_menus() {
            'primary-menu' => __( 'Primary Menu' ),
            'personal-menu' => __( 'Personal Menu' )

in a post.fields.php that i've created, don't work. :(

Link to existing code.

Can you help me in that fantastic problem? :(

ps: Sorry for my bad english


  • I made an update to my answer and included a filter function you can use. – fuxia Feb 10 '12 at 0:37

To see how such a list can be created look at the code in wp-admin/includes/nav-menu.php. Unfortunately, it is hard coded there, so you have to re-create the code.

First, let’s create two menus:

enter image description here

We can get these menus in PHP with wp_get_nav_menus() (a wrapper for get_terms()):

$menus = wp_get_nav_menus();
print '<pre>' . htmlspecialchars( print_r( $menus, TRUE ) ) . '</pre>';


    [0] => stdClass Object
            [term_id] => 5
            [name] => Paradigmatic Inconvenience
            [slug] => paradigmatic-inconvenience
            [term_group] => 0
            [term_taxonomy_id] => 5
            [taxonomy] => nav_menu
            [description] => 
            [parent] => 0
            [count] => 0

    [1] => stdClass Object
            [term_id] => 6
            [name] => Paul
            [slug] => paul
            [term_group] => 0
            [term_taxonomy_id] => 6
            [taxonomy] => nav_menu
            [description] => 
            [parent] => 0
            [count] => 0

Now we build the selector function:

 * Build a dropdown selector for all existing nav menus.
 * @author Thomas Scholz, toscho.de
 * @param  string $name     Used as name attribute for the select element.
 * @param  string $selected Slug of the selected menu
 * @param  bool   $print    Print output or just return the HTML.
 * @return string
function t5_nav_menu_drop_down( $name, $selected = '', $print = TRUE )
    // array of menu objects
    $menus = wp_get_nav_menus();
    $out   = '';

    // No menu found.
    if ( empty ( $menus ) or is_a( $menus, 'WP_Error' )  )
        // Give some feedback …
        $out .= __( 'There are no menus.', 't5_nav_menu_per_post' );

        // … and make it usable …
        if ( current_user_can( 'edit_theme_options' ) )
            $out .= sprintf(
                __( ' <a href="%s">Create one</a>.', 't5_nav_menu_per_post' ),
                admin_url( 'nav-menus.php' )
        // … and stop.
        $print and print $out;
        return $out;

    // Set name and ID to let you use a <label for='id_$name'>
    $out = "<select name='$name' id='id_$name'>\n";

    foreach ( $menus as $menu )
        // Preselect the active menu
        $active = $selected == $menu->slug ? 'selected' : '';
        // Show the description
        $title  = empty ( $menu->description ) ? '' : esc_attr( $menu->description );

        $out .= "\t<option value='$menu->slug' $active $title>$menu->name</option>\n";

    $out .= '</select>';

    $print and print $out;
    return $out;

Calling this function …

t5_nav_menu_drop_down( 'my_nav_select', 'paul' );

… will give us a nice, simple select element with 'paul' pre-selected:

enter image description here

Now we need a meta box to offer the selector to our post authors. To keep this short, I just use a child class of my Basic Meta Box. Basically, you call the function in the meta box and save the menu slug as post meta.

enter image description here

Then you can access the selected nav menu slug in your theme per:

get_post_meta( get_the_ID(), '_t5_nav_menu_per_post', TRUE );

Another way to get the full nav menu in your theme:

// Print a wp_nav_menu
    // an array of wp_nav_menu() arguments.
    array ( 
        'menu' => 'default-menu',
        // you may set a custom post ID
        'post_id' => get_the_ID() 

Because I like your idea very much I’ve added a theme helper function and mangled everything into a plugin. Get it on GitHub: T5 Nav Menu Per Post.

Oh, and welcome to WordPress Stack Exchange. Don’t worry about your English as long as you ask – and answer – interesting questions. :)


To use the plugin with a custom post type like your portfolio just install the plugin, activate it and add the following code to the file where you register the custom post type:

add_filter( 't5_nav_menu_per_post_post_types', 'wpse41695_add_post_type' );

function wpse41695_add_post_type( $post_types )
    $post_types[] = 'portfolios';
    return $post_types;

Your code still has many problems: global variables, missing prefixes, weird indentation. Recommended reading: Coding Standards and prefix everything.

  • Pretty kool! +1 – kaiser Feb 10 '12 at 8:47
  • Ok, it work and the one of these problem is: i see the dropmenu everywhere, in admin pages and themes :S :D And the second problem: how can i put in the box at the right of Portfolio? so: i called the t5_nav_menu_drop_down( 'my_nav_select', 'paul' );, but how can i put in the box? with Basic Meta Box? and how? :( sorry for nooby :( – user12932 Feb 11 '12 at 1:48
  • Yes, i've resolved, simply: i paste your code (the add_filter) in the php of your plugin Nav Menu Per Post :).... – user12932 Feb 11 '12 at 2:22
  • Ops, i passed 5 minutes because i want edit my last comment...so, i've two problem for theme: how can i get the code? i've put the code get_post_meta( get_the_ID(), '_t5_nav_menu_per_post', TRUE ); in the post.php but don't work...and the second: how can i put the class and id in this custom nav? thank you very much! :) – user12932 Feb 11 '12 at 2:31
  • And the third problem : if i save the portfolio (ONLY THE CUSTOM PORTFOLIO, because with the post/article it work!), it no remain selected...it return to "Pick one"...how can i resolve? thank you more! :( – user12932 Feb 11 '12 at 2:42

Had the same problem regarding the custom post_type not saving the data. It was due to it failing save_allowed() in basic_meta_box.php.

current_user_can('edit_'.$_POST['post_type'],$post_id) which with a custom post type resolves to current_user_can('edit_portfolio',$post_id) - which fails in wordpress. need to change to a valid capability like edit_others_pages or edit_pages.

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.