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
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
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: