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.

I'm looking for ways to prevent "private" and "draft" pages from appearing (to non-logged-in admins) in a site's Primary Navigation menu which is based on a custom menu - other than manually removing such pages from the WP custom menu and then dragging them back when they are published, that is.

FWIW, I'm surprised the behavior I'm looking for isn't the default.

Using: WP 3.4.2

share|improve this question
To clarify: what code are you using to output your "custom menu"? –  Ben Oct 11 '12 at 18:58
None (if I understand your question). This happens using the current Twenty-Ten theme (v1.4) with no customization - other than having created a Custom Menu in the "Appearance" subpanel and assigning it to Primary Navigation in the "Theme Locations" section. –  Jeff Cohan Oct 11 '12 at 19:36
Here is a solution that filters drafts from wp_nav_menu: wordpress.org/support/topic/… –  user24720 Dec 12 '12 at 11:04

2 Answers 2

I used this as a solution for hiding draft pages. You can hide the (draft page) menu items with the li.draft class.

add_filter('nav_menu_css_class' , 'nav_menu_add_post_status_class' , 10 , 2);
function nav_menu_add_post_status_class($classes, $item){
    $post_status = get_post_status($item->object_id);
    $classes[] = $post_status;
    return $classes;

FWIW: I feel the same way ;-)

share|improve this answer

The easiest solution is to add a specific class to the menu items that you want to hide. And then hide them through CSS.

custom nav menu classes
^ click to enlarge ^

The CSS classes are not visible by default, you have to enable it in the Screen Options upper tab.

If your theme does not print the relevant classes in the <body> tag, this will do:

add_filter( 'body_class', 'wpse_67929_body_class' );

function wpse_67929_body_class( $classes ) 
    if( !is_user_logged_in() )
        $classes[] = 'not-logged-menu';

    return $classes;

Finally, in your style.css, add this rule:

body.not-logged-menu .menu-logged-in {display:none}

Another option, use the following filter:

add_filter('wp_nav_menu_items', 'wpse_67929_nav_menu_items', 10, 2 );

function wpse_67929_nav_menu_items( $nav_menu, $args )
    // Manipulate the output
    // $nav_menu contains a single string with the menu Html structure
    // more or less like this: 
    // <li id class><a href>Menu Item</a></li> <ul><li><a>Submenu Item</li></ul> <etc>
    return $nav_menu;

"Manipulate the output" seems simple but reveals to be tricky:

share|improve this answer

Your Answer


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.