checkbox in post add/edit to add/remove the post from menu

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

2 Answers
2

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

Leave a Comment