Skip to content

Instantly share code, notes, and snippets.

@awshout
Last active August 19, 2023 02:44
Show Gist options
  • Save awshout/3943026 to your computer and use it in GitHub Desktop.
Save awshout/3943026 to your computer and use it in GitHub Desktop.
WordPress Menu & Walker for ZURB's Foundation 4 Top Bar

Adding a Foundation Top Bar to WordPress

foundation-topbar-menu.php and foundation-topbar-walker.php should be required in the WordPress functions.php file.

The code in foundation-topbar.php should be added below the body tag in header.php

Setup a menu in WordPress admin under Appearance > Menus

Use the 'label' class on a menu item to create a menu section title

Foundation Top Bar Doc: http://foundation.zurb.com/docs/components/top-bar.html

<?php
add_theme_support('menus');
/**
* Register Menus
* http://codex.wordpress.org/Function_Reference/register_nav_menus#Examples
*/
register_nav_menus(array(
'top-bar-l' => 'Left Top Bar', // registers the menu in the WordPress admin menu editor
'top-bar-r' => 'Right Top Bar'
));
/**
* Left top bar
* http://codex.wordpress.org/Function_Reference/wp_nav_menu
*/
function foundation_top_bar_l() {
wp_nav_menu(array(
'container' => false, // remove nav container
'container_class' => '', // class of container
'menu' => '', // menu name
'menu_class' => 'top-bar-menu left', // adding custom nav class
'theme_location' => 'top-bar-l', // where it's located in the theme
'before' => '', // before each link <a>
'after' => '', // after each link </a>
'link_before' => '', // before each link text
'link_after' => '', // after each link text
'depth' => 5, // limit the depth of the nav
'fallback_cb' => false, // fallback function (see below)
'walker' => new top_bar_walker()
));
}
/**
* Right top bar
*/
function foundation_top_bar_r() {
wp_nav_menu(array(
'container' => false, // remove nav container
'container_class' => '', // class of container
'menu' => '', // menu name
'menu_class' => 'top-bar-menu right', // adding custom nav class
'theme_location' => 'top-bar-r', // where it's located in the theme
'before' => '', // before each link <a>
'after' => '', // after each link </a>
'link_before' => '', // before each link text
'link_after' => '', // after each link text
'depth' => 5, // limit the depth of the nav
'fallback_cb' => false, // fallback function (see below)
'walker' => new top_bar_walker()
));
}
?>
<?php
/**
* Customize the output of menus for Foundation top bar
*/
class top_bar_walker extends Walker_Nav_Menu {
function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
$element->has_children = !empty( $children_elements[$element->ID] );
$element->classes[] = ( $element->current || $element->current_item_ancestor ) ? 'active' : '';
$element->classes[] = ( $element->has_children ) ? 'has-dropdown' : '';
parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
$item_html = '';
parent::start_el( $item_html, $object, $depth, $args );
$output .= ( $depth == 0 ) ? '<li class="divider"></li>' : '';
$classes = empty( $object->classes ) ? array() : (array) $object->classes;
if( in_array('label', $classes) ) {
$output .= '<li class="divider"></li>';
$item_html = preg_replace( '/<a[^>]*>(.*)<\/a>/iU', '<label>$1</label>', $item_html );
}
if ( in_array('divider', $classes) ) {
$item_html = preg_replace( '/<a[^>]*>( .* )<\/a>/iU', '', $item_html );
}
$output .= $item_html;
}
function start_lvl( &$output, $depth = 0, $args = array() ) {
$output .= "\n<ul class=\"sub-menu dropdown\">\n";
}
}
?>
<div class="top-bar-container fixed contain-to-grid">
<nav class="top-bar">
<ul class="title-area">
<li class="name">
<h1><a href="<?php echo home_url(); ?>"><?php bloginfo('name'); ?></a></h1>
</li>
<li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
</ul>
<section class="top-bar-section">
<?php foundation_top_bar_l(); ?>
<?php foundation_top_bar_r(); ?>
</section>
</nav>
</div>
@StefsterNYC
Copy link

Ah this is awesome. I'm so close. Nothing showing up though. Using F5 but so far no luck. What am I missing?

  1. Both .php files are in a inc folder.
  2. Markup in header
  3. Calling both php from functions file.

Did I miss something?

@StefsterNYC
Copy link

Ah! I got it working. Awesome.

@maddtechwf
Copy link

I'm using F5 also. I have the navigation working but when it gets to a smart phone screen it doesn't work for some reason. Any ideas why?

** I FOUND THE FIX. If you downloaded Foundation 5.0.0 then you will have issues. If you download 5.0.1 or 5.0.2 it will fix it for you.

@Maikenvv
Copy link

Thank you so much for this code. I've got Foundation 5.0.2. working with normal nav and mobile. I'm wondering if anyone also had a problem with the dropdown menu's. I can't get them to work. I can click on the parent, and darkens it's color, but no dropdown appears. I've already tried z-index.

@demo38
Copy link

demo38 commented Dec 16, 2013

Sending positive vibes - because you deserve them. Thanks for taking the time to put this together - hugely useful. @awshout

@nilocoelhojunior
Copy link

Thank you so much for this code

@StefsterNYC
Copy link

I'm not sure if anyone commented on this so I'm just going to throw this out there. When the menu goes below 767px a parent tab that has a page attached to it and children becomes a non usable tab. You click on it and it just slides the menu over to the children rather than actually going to that page. Has anyone else experienced that and if so what was the fix to this? Thanks.

@bei-soan
Copy link

@StefsterNYC I have this issue too, but on every size. Do you have any news about this issue already?

@mmerriweather
Copy link

@aweshout I used the function you wrote to add a search input to the right menu, and it is not showing up in the top bar menu. I added the function inside foundation-topbar-menu.php. Was that the wrong place to add it?

<div class="top-bar-container fixed contain-to-grid">
            <nav class="top-bar" data-topbar>
                <ul class="title-area">
                    <li class="name">
                        <h1><a href="<?php echo home_url(); ?>"><?php bloginfo('name'); ?></a></h1>
                    </li>          
                    <li class="toggle-topbar menu-icon"><a href="#"><span>Menu</span></a></li>
                </ul>
                <section class="top-bar-section">
                    <?php foundation_top_bar_l(); ?>
                    <?php foundation_top_bar_r(); ?>
                    <ul class="right"><li><?php top_bar_search(); ?></li>


                </section>
            </nav>
        </div>
{
    // code
}

@jeremybutler
Copy link

Very useful and time saving, thanks for making this public!

@flowdee
Copy link

flowdee commented May 9, 2014

manually added the "not-click" class which reactivated the dropdown but the mobile/responsive navigation doesn't work any more. suggestions? i click the icon but nothing happens

@rosemckeon
Copy link

@flowdee check you have this in your head,

<meta name="viewport" content="width=device-width">

@captaincoffee
Copy link

Can anyone point to a functioning starter theme that incorporates this? It would be very helpful to see exactly how this is implemented within the various files. Especially for us beginners. Thanks.

@patrick-wc
Copy link

Excellent!

For the search form, or anything at the end of the menu I used this code:

add_filter( 'wp_nav_menu_items', 'your_custom_menu_item', 10, 2 );
function your_custom_menu_item ( $items, $args ) {
    if ($args->theme_location == 'top-bar-r') {
        $items .= '<li class="has-form">';
        $items .= '    <form role="search" class="searchform" method="get" action="' . home_url() . '">';
        $items .= '        <div>';
        $items .= '            <input id="sf-s" name="s" value="' . get_search_query() . '" type="text" onkeyup="buttonUp()" placeholder="Search..." />';
        $items .= '            <input id="sf-searchsubmit" type="submit" value="" />';
        $items .= '            <span class="search-icon-toggle" title="Click to Search"></span>';
        $items .= '        </div>';
        $items .= '    </form>';
        $items .= '</li>';
    }
    return $items;
}

(Obviously use whatever HTML you need)

@sabotawsh
Copy link

I'm trying to add the description

if ( !empty( $item->description ) ) {
    $item_html .= '<span class="description">' . esc_attr( $item->description ) . '</span>';
}

But I'm unsure of where to place it amongst all this:

/ CUSTOMIZE THE OUTPUT OF MENUS FOR FOUNDATION TOP BAR 
class top_bar_walker extends Walker_Nav_Menu {

    function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
        $element->has_children = !empty( $children_elements[$element->ID] );
        $element->classes[] = ( $element->current || $element->current_item_ancestor ) ? 'active' : '';
        $element->classes[] = ( $element->has_children ) ? 'has-dropdown' : '';

        parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
    }

    function start_el( &$output, $object, $depth = 0, $args = array(), $current_object_id = 0 ) {
        $item_html = '';
        parent::start_el( $item_html, $object, $depth, $args ); 

        // $output .= ( $depth == 0 ) ? '<li class="divider"></li>' : '';

        $classes = empty( $object->classes ) ? array() : (array) $object->classes;  

        if( in_array('label', $classes) ) {
            $output .= '<li class="divider"></li>';
            $item_html = preg_replace( '/<a[^>]*>(.*)<\/a>/iU', '<label>$1</label>', $item_html );
        }

    if ( in_array('divider', $classes) ) {
        $item_html = preg_replace( '/<a[^>]*>( .* )<\/a>/iU', '', $item_html );
    }

        $output .= $item_html;
    }

    function start_lvl( &$output, $depth = 0, $args = array() ) {
        $output .= "\n<ul class=\"sub-menu dropdown\">\n";
    }

}

And also don't I have to add it to call it out in my arguments with something like this?

'walker' => new description_walker()

So far everywhere I've tested adding it, has failed.

@Warkman
Copy link

Warkman commented Nov 27, 2014

The fix to have the dropdown work in foundation 5 (WP 4.1) is change in foundation4-topbar.php file, line 2:

from
<nav class="top-bar">
to
<nav class="top-bar" data-topbar>

Copy link

ghost commented Dec 30, 2014

thank you for this awshout, it helped a lot!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment