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 trying to add a class to the body tag based on whether current menu items either have children, or are children. The custom menu was added via wp_nav_menu.

I have hooked into wp_nav_menu_objects via a filter, and am successfully detecting whether the current active menu item is a ancestor or child:

function has_submenu( $menu_items ) {

    $current_id = 0;

    foreach( $menu_items as $menu_item ) {

        // Get the id of the current menu item
        if( $menu_item->current ) {
            $current_id = $menu_item->ID;
        }
        // if the current item has a child
        if( $menu_item->menu_item_parent != 0 && $menu_item->menu_item_parent == $current_id ) {
            $body_class = 'has-submenu';
            break;
        }
        // if the current item has an ancestor
        if( $menu_item->current_item_ancestor ) {
            $body_class = 'is-submenu';
            break;
        }
    }
    return $menu_items;
}
add_filter( 'wp_nav_menu_objects', 'has_submenu', 10, 2 );

Now the issue i'm having is how to I then filter body_class to add the class?? I created the variable called $body_class, however i'm not sure hot to pass it to the body_class hook function. Make it a global variable? Create a class for all this?

Thanks in advance!

share|improve this question
    
When you print the menu, the body class was already outputted. Is not possible with php modify something already printed to browser. You have to use javascript. –  G. M. Sep 13 '13 at 23:24
    
Perhaps if you tell us why you want to add 'is-submenu' or 'has-submenu' to the body class, we can help you find a different solution. –  Charles Clarkson Sep 13 '13 at 23:31
    
@G.M. you're totally right, I need to hook into the menu before the body tag is called. –  plankguy Sep 13 '13 at 23:59
    
@CharlesClarkson The menu is fixed/sticky at the top of the page. On pages where there is either a child menu, or is a child page, the sub menu (level 2) is visible. So i need/want to add a class to the body, so I can move the content down via CSS so the fixed menu doesn't overlap. I was hoping to find a non-js solution. –  plankguy Sep 14 '13 at 0:01

1 Answer 1

up vote 0 down vote accepted

As @CharlesClarkson has already explained, you cannot modify the page output with PHP after the output has been sent to the browser. Your menu certainly runs after body_class since the menu must run inside the <body> tag.

The only PHP solution I see would involve editing your theme templates in addition to the code above (with changes).

If you run wp_nav_menu before the <body> tag but use output buffering to capture the content instead of print it, what you are trying to do might work.

You would need to run your menu before the <body> tag, like this:

ob_start();
wp_nav_menu();
$my_captured_menu = ob_get_contents();
ob_end_clean();

In your function callback, instead of lines like this:

$body_class = 'has-submenu';

You would need this:

add_filter(
  'body_class',
  function($classes) {
    $classes[] = 'has-submenu'; // or 'is-submenu'
    return $classes;
  }
);

And of course, use echo $my_captured_menu wherever it needs to be printed.

share|improve this answer

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.