Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

Introduction:

I have created several post type for my theme. To display a post from a post-type I need to go in appearance/menu and then add the post manually.

My Goal:

I want to add two radio buttons in the post add/edit page to choose whether the current post will be in menu.

Attempts:

So I have created the checkbox in post-type add/edit page. Looks like enter image description here

Everything works fine, the status is saved, now I want before saving to add/remove it in the menu list as sub-menu with for parent its post-type, how could I achieve that?

Here is what I have done so far:

// create post type
add_action( 'init', 'create_post_type' );
function create_post_type() {

    $conf = array(
        'public' => true,
        'has_archive' => true,
        'menu_position' => 5,
        'show_in_nav_menus' => true,
        'hierarchical' => true,
        'has_archive' => true,
        'supports' => array('title', 'editor', 'content', 'page-attributes'),
        'taxonomies' => array('category', 'post_tag'),

        );

    $conf['labels'] = array(
        'name' => __( 'Architecte Posts' ),
        'singular_name' => __( 'Architecte' )
        );
    $conf['rewrite'] = array('slug' => 'architect');

    register_post_type( 'architect_subpage',$conf);


    $conf['labels'] = array(
        'name' => __( 'Interior Posts' ),
        'singular_name' => __( 'Interior' )
        );
    $conf['rewrite'] = array('slug' => 'interior');
    register_post_type( 'interior_subpage',$conf);
}

// remove posts menu since it's not in use
function remove_menus () {
    global $menu;
    $restricted = array(__('Posts'));
    end ($menu);
    while (prev($menu)){
        $value = explode(' ',$menu[key($menu)][0]);
        if(in_array($value[0] != NULL?$value[0]:"" , $restricted)){unset($menu[key($menu)]);}
    }
}
add_action('admin_menu', 'remove_menus');




/* Define the custom box */
add_action( 'add_meta_boxes', 'wpse_61041_add_custom_box' );

/* Do something with the data entered */
add_action( 'save_post', 'wpse_61041_save_postdata' );

/* Adds a box to the main column on the Post and Page edit screens */
function wpse_61041_add_custom_box() {
    add_meta_box(
        'wpse_61041_sectionid',
        'Publish in Menu',
        'wpse_61041_inner_custom_box',
        'architect_subpage',
        'side',
        'high'
    );
}

/* Prints the box content */
function wpse_61041_inner_custom_box($post)
{
    // Use nonce for verification
    wp_nonce_field( 'wpse_61041_wpse_61041_field_nonce', 'wpse_61041_noncename' );

    // Get saved value, if none exists, "default" is selected
    $saved = get_post_meta( $post->ID, 'in_menu', true);
    if( !$saved )
        $saved = 'no';

    $fields = array(
        'yes'       => __('Yes', 'wpse'),
        'no'     => __('No', 'wpse'),
    );

    foreach($fields as $key => $label)
    {
        printf(
            '<input type="radio" name="in_menu" value="%1$s" id="in_menu[%1$s]" %3$s />'.
            '<label for="in_menu[%1$s]"> %2$s ' .
            '</label><br>',
            esc_attr($key),
            esc_html($label),
            checked($saved, $key, false)
        );
    }
}

/* When the post is saved, saves our custom data */
function wpse_61041_save_postdata( $post_id )
{
      // verify if this is an auto save routine.
      // If it is our form has not been submitted, so we dont want to do anything
      if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
          return;

      // verify this came from the our screen and with proper authorization,
      // because save_post can be triggered at other times
      if ( !wp_verify_nonce( $_POST['wpse_61041_noncename'], 'wpse_61041_wpse_61041_field_nonce' ) )
          return;

      if ( isset($_POST['in_menu']) && $_POST['in_menu'] != "" ){

            update_post_meta( $post_id, 'in_menu', $_POST['in_menu'] );

      }
}

https://gist.github.com/roine/4994447

share|improve this question
    
Welcome to WordPress Stack Exchange! Would you be able to post the code you have so far? It would be a big help –  bungeshea Feb 20 '13 at 10:07
    
@bungeshea yep I added a gist –  Jonathan de M. Feb 20 '13 at 10:10
    
I don't get this: "add/remove it in the menu list as sub-menu with for parent its post-type"... Are you referring to a Nav-Menu? –  brasofilo Feb 24 '13 at 17:08
    
@brasofilo, yes –  Jonathan de M. Feb 25 '13 at 1:48
add comment

2 Answers 2

I have changed the code of brasofilo, and added the ability to add the post as a child

Here is the resivion: https://gist.github.com/roine/5105421/revisions

And here is the full code (also available here):

<?php
add_action( 'add_meta_boxes', 'add_custom_box_wpse_87594' );
add_action( 'save_post', 'save_postdata_wpse_87594', 10, 2 );

function add_custom_box_wpse_87594() 
{
    add_meta_box( 
        'section_id_wpse_87594',
        __( 'Available Nav-Menus' ),
        'inner_custom_box_wpse_87594',
        'post',
        'side'
    );
}

function inner_custom_box_wpse_87594() 
{
    $navmenus = wp_get_nav_menus( array( 'hide_empty' => false, 'orderby' => 'none' ) );

    // DEBUG
    // echo '<pre>' . print_r( $navmenus, true ) . '</pre>';

    wp_nonce_field( plugin_basename( __FILE__ ), 'noncename_wpse_87594' );

    echo '<select name="nav_menus_dropdown" id="nav_menus_dropdown">
        <option value="">- Select -</option>';

    foreach( $navmenus as $m ) 
    {
        echo "<optgroup label='$m->name'>";
        echo "<option value={$m->term_id}>&#8593; Add on top</option>";
        $items = wp_get_nav_menu_items( $m->term_id);
        foreach ($items as $key => $menu_item ) {
           if(!$menu_item->menu_item_parent){
              printf('<option value="%s-%s">%s</option>',
              $m->term_id,
              $menu_item->object_id,
              $menu_item->title);
           }
           echo "</optgroup>";
        }

    echo '</select>';   
    }
}

function save_postdata_wpse_87594( $post_id, $post_object ) 
{
    // Auto save?
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )  
        return;

    // Security
    if ( 
        !isset( $_POST['noncename_wpse_87594'] ) 
        || !wp_verify_nonce( $_POST['noncename_wpse_87594'], plugin_basename( __FILE__ ) ) 
        )
        return;

    // Correct post_type
    if ( 'post' != $post_object->post_type )
        return;

    if( !empty( $_POST['nav_menus_dropdown'] ) )
    {
        $parents = explode('-', $_POST['nav_menus_dropdown']);
        $item = array(
            'menu-item-title' => $_POST['post_title'],
            'menu-item-object' => 'page',
            'menu-item-object-id' => $_POST['ID'],
            'menu-item-type' => 'post_type',
            'menu-item-status' => 'publish'
        );
        if(count($parents) > 1){
           $item['menu-item-parent-id'] = $parents[1];
        }
        wp_update_nav_menu_item(
            $_POST['nav_menus_dropdown'], 
            0, 
            $item
        );
    }       
}

It works for me but still could be improved.

Behavior:

It will display the top level items of each menu in the dropdown list, also Add on top will add the post as a top level instead of as a child

enter image description here

share|improve this answer
add comment

The following is just a proof of concept and needs to be adapted/improved to work per the Question requirements.

It creates a meta box with a dropdown listing all available Navigation Menus. On post save, it is added to the selected menu.

This Q&A was used as starting point: Programmatically add a Navigation menu and menu items. The relevant functions are wp_get_nav_menus and wp_update_nav_menu_item. I'm not sure how to remove a menu item, but probably wp_delete_post must be used.

add_action( 'add_meta_boxes', 'add_custom_box_wpse_87594' );
add_action( 'save_post', 'save_postdata_wpse_87594', 10, 2 );

function add_custom_box_wpse_87594() 
{
    add_meta_box( 
        'section_id_wpse_87594',
        __( 'Available Nav-Menus' ),
        'inner_custom_box_wpse_87594',
        'post',
        'side'
    );
}

function inner_custom_box_wpse_87594() 
{
    $navmenus = wp_get_nav_menus( array( 'hide_empty' => false, 'orderby' => 'none' ) );

    // DEBUG
    // echo '<pre>' . print_r( $navmenus, true ) . '</pre>';

    wp_nonce_field( plugin_basename( __FILE__ ), 'noncename_wpse_87594' );

    echo '<select name="nav_menus_dropdown" id="nav_menus_dropdown">
        <option value="">- Select -</option>';

    foreach( $navmenus as $m ) 
    {
        printf( 
            '<option value="%s">%s</option>',
            $m->term_id,
            $m->name
        );
    }

    echo '</select>';   
}

function save_postdata_wpse_87594( $post_id, $post_object ) 
{
    // Auto save?
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )  
        return;

    // Security
    if ( 
        !isset( $_POST['noncename_wpse_87594'] ) 
        || !wp_verify_nonce( $_POST['noncename_wpse_87594'], plugin_basename( __FILE__ ) ) 
        )
        return;

    // Correct post_type
    if ( 'post' != $post_object->post_type )
        return;

    if( !empty( $_POST['nav_menus_dropdown'] ) )
    {
        wp_update_nav_menu_item(
            $_POST['nav_menus_dropdown'], 
            0, 
            array(
                'menu-item-title' => $_POST['post_title'],
                'menu-item-object' => 'page',
                'menu-item-object-id' => $_POST['ID'],
                'menu-item-type' => 'post_type',
                'menu-item-status' => 'publish'
            )
        );
    }       
}

Result:
navigation menus meta box

share|improve this answer
    
I really like this idea. I would be very interested in seeing the finished product. I think a feature like this could be added as a default function in WordPress and I think you should submit the idea to the powers that be –  Jamie Mar 6 '13 at 15:27
    
Nice job @brasofilo –  Jonathan de M. Mar 7 '13 at 4:08
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.