Zurb Foundation 5 and WordPress Menus

For those of us into writing WordPress themes, who also want to make use of the brilliant Zurb Foundation framework, here’s a quick guide on how to get WordPress to generate its menus with the added classes that Foundation expects.

For future reference, this guide applies to Foundation 5.0.3 and WordPress 3.8

Introduction

Foundation expects its ‘top-bar’ menu to be laid out in the following format:

<nav class="top-bar" data-topbar>
  <ul class="title-area">
    <li class="name">
      <h1><a href="#">My Site</a></h1>
    </li>
    <li class="toggle-topbar menu-icon"><a href="#">Menu</a></li>
  </ul>

  <section class="top-bar-section">
    <!-- Right Nav Section -->
    <ul class="right">
      <li class="active"><a href="#">Right Button Active</a></li>
      <li class="has-dropdown">
        <a href="#">Right Button with Dropdown</a>
        <ul class="dropdown">
          <li><a href="#">First link in dropdown</a></li>
        </ul>
      </li>
    </ul>

    <!-- Left Nav Section -->
    <ul class="left">
      <li><a href="#">Left Nav Button</a></li>
    </ul>
  </section>
</nav>

We’re going to get WordPress to generate the <ul> just below <!– Right Nav Section –> in the example above.

[GARD]

 

WordPress Menus

Three things are required to get WordPress to output menus in the above format.

Call wp_nav_menu() with Appropriate Arguments

In your header.php copy the example above, and then replace the whole of the <ul> just below the <!–Right Nav Section–> with this:

<?php
$options = array(
  'theme_location' => 'primary',
  'container' => false,
  'depth' => 2,
  'items_wrap' => '<ul id="%1$s" class="right %2$s">%3$s</ul>',
  'walker' => new GC_walker_nav_menu()
);
wp_nav_menu($options); ?>

This will output the ‘primary’ WordPress menu (as defined in your functions.php file) with the following settings:

  • It will not be wrapped in any container. <div> and <nav> are both possible but unwanted here.
  • It will output to a max depth of 2 sub-menus. Foundation does not display further than this, so there’s no point!
  • The parent <ul> will contain its usual generated id and the ‘menu’ class. The ‘right’ class with also be added. This is only necessary if you want your menu to float right.
  • The menu will be generated using the GC_walker_nav_menu. This is the important bit!

Create A Custom Menu Walker

The menu walker is a class that WordPress uses to generate its menu output. Specifically here, we’re after adding the ‘dropdown’ class to the <ul>’s that contain sub-menu items.

Add the following class to your functions.php:

class GC_walker_nav_menu extends Walker_Nav_Menu {

  // add classes to ul sub-menus
  function start_lvl(&$output, $depth) {
    // depth dependent classes
    $indent = ( $depth > 0 ? str_repeat("\t", $depth) : '' ); // code indent

    // build html
    $output .= "\n" . $indent . '<ul class="dropdown">' . "\n";
  }
}

So now every new ‘level’, i.e. sub-menu <ul>’s, will be assigned the ‘dropdown’ class.

Add Class to Parent <li>’s

Finally also add this to your functions.php file:

if (!function_exists('GC_menu_set_dropdown')) :
function GC_menu_set_dropdown($sorted_menu_items, $args) {
  $last_top = 0;
  foreach ($sorted_menu_items as $key => $obj) {
    // it is a top lv item?
    if (0 == $obj->menu_item_parent) {
      // set the key of the parent
      $last_top = $key;
    } else {
      $sorted_menu_items[$last_top]->classes['dropdown'] = 'has-dropdown';
    }
  }

  return $sorted_menu_items;
}
endif;
add_filter('wp_nav_menu_objects', 'GC_menu_set_dropdown', 10, 2);

So now all parent <li>’s that contain sub-menus will be assigned the ‘has-dropdown’ class.

WordPress is now generating menus in a format that makes sense to Zurb Foundation. You should be seeing working menus in your WordPress theme! However, life’s never simple and there’s a couple of other little niggles to sort out…

[GARD]

 

Mobile Navigation Problems

Now, when Foundation displays the menu on a small screen it collapses down to the ‘hamburger’ icon, and displays a dropdown menu when the user clicks the icon. Unfortunately, top-level menu items now become un-clickable as they just slide away to reveal the sub-menu beneath them.

Right back at the top, I contained the whole top-bar menu within ‘<nav data-topbar>’. The addition below makes top-level items appear in their own sub-menus so that the menu is navigable on mobile. I think this should be default behaviour.

<nav class="top-bar" data-topbar data-options="mobile_show_parent_link: true">

Sticky Class Interactions

Our final problem is that both Zurb Foundation and WordPress use the .sticky class.

Foundation uses it to make menus that might appear a little way down the page ‘stick’ to the top of the page when you scroll down, so that they are always visible.

WordPress uses .sticky to mark out sticky posts, simply for later CSS styling.

Remove WordPress .sticky Class

The following function will stop WordPress from using the sticky class, and style WordPress sticky posts using the .wordpress-sticky class instead. Thanks to envex for this one. It’s simpler than modifying Foundation to use a different class.

function remove_sticky_class($classes) {
  $classes = array_diff($classes, array("sticky"));
  $classes[] = 'wordpress-sticky';
  return $classes;
}
add_filter('post_class','remove_sticky_class');

[GARD]

 

All Done!

That’s it. We’re done. Hope you found it useful. Let me know if you’ve any suggestions for improvements in the comments below. And perhaps have a little click of the Flattr button, or on some of the adverts… They help pay my hosting costs!

If you’re looking to write your own WordPress theme using Foundation 5, I’ve created a base theme that can be used as a starting point.


COMMENTS

2 thoughts on “Zurb Foundation 5 and WordPress Menus