Adding a Nav menu to post admin

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.

Read More

I’ve copied the rows:

add_action( 'init', 'register_my_menus' );
function register_my_menus() {
    register_nav_menus(
        array(
            '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

Francesco

Related posts

Leave a Reply

2 comments

  1. 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>';
    

    Output:

    Array
    (
        [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
    do_action( 
        't5_custom_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. 🙂

    Update

    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.

  2. 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.