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'] );
}
}
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
andwp_update_nav_menu_item
. I’m not sure how to remove a menu item, but probablywp_delete_post
must be used.Result:
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):
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