Coder Social home page Coder Social logo

wp-bootstrap / wp-bootstrap-navwalker Goto Github PK

View Code? Open in Web Editor NEW
3.4K 212.0 2.0K 581 KB

A custom WordPress nav walker class to fully implement the Twitter Bootstrap 4.0+ navigation style (v3-branch available for Bootstrap 3) in a custom theme using the WordPress built in menu manager.

Home Page: https://wp-bootstrap.github.io/wp-bootstrap-navwalker/

License: GNU General Public License v3.0

PHP 93.29% Shell 6.71%
wp-bootstrap-navwalker walker bootstrap wordpress nav navigation twitter-bootstrap php wordpress-theme custom-theme

wp-bootstrap-navwalker's Introduction

WP Bootstrap Navwalker

Code Climate Test Coverage Issue Count Build Status Scrutinizer Code Quality Code Coverage Build Status

This code in the main repo branch is undergoing a big shakeup to bring it in line with recent standards and to merge and test the backlog of PRs I have left for too long. Please use the v4.3.0 tag for stable version while this process happens. https://github.com/wp-bootstrap/wp-bootstrap-navwalker/releases/tag/v4.3.0

A custom WordPress Nav Walker Class to fully implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager.

NOTES

This is a utility class that is intended to format your WordPress theme menu with the correct syntax and CSS classes to utilize the Bootstrap dropdown navigation. It does not include the required Bootstrap JS and CSS files - you will have to include them manually.

WordPress.org Theme Compliance

This walker is fully compliant with all Theme Review guidelines for wordpress.org theme submission. It requires no modification to be compliant but you can optionally replace the wp-bootstrap-navwalker text domain (which appears twice in the fallback function) with the text domain of your theme.

Upgrade Notes

Between version 3 and version 4 of the walker there have been significant changes to the codebase. Version 4 of the walker is built to work with Bootstrap 4 and has not been tested for backwards compatibility with Bootstrap 3. A separate branch for Bootstrap 3 is maintained here: https://github.com/wp-bootstrap/wp-bootstrap-navwalker/tree/v3-branch

Here is a list of the most notable changes:

  • The filename has been changed and prefixed with class- to better fit PHP coding standards naming conventions.
    • New Name: class-wp-bootstrap-navwalker.php
    • Old Name: wp-bootstrap-navwalker.php
  • Icon and link modifier handling is now done through the CSS Classes menu item input instead of the Title input.
  • Icon only items are possible using icon classes in combination with the sr-only classname.

Installation

Place class-wp-bootstrap-navwalker.php in your WordPress theme folder /wp-content/themes/your-theme/

Open your WordPress themes functions.php file - /wp-content/themes/your-theme/functions.php - and add the following code:

/**
 * Register Custom Navigation Walker
 */
function register_navwalker(){
	require_once get_template_directory() . '/class-wp-bootstrap-navwalker.php';
}
add_action( 'after_setup_theme', 'register_navwalker' );

If you encounter errors with the above code use a check like this to return clean errors to help diagnose the problem.

if ( ! file_exists( get_template_directory() . '/class-wp-bootstrap-navwalker.php' ) ) {
    // File does not exist... return an error.
    return new WP_Error( 'class-wp-bootstrap-navwalker-missing', __( 'It appears the class-wp-bootstrap-navwalker.php file may be missing.', 'wp-bootstrap-navwalker' ) );
} else {
    // File exists... require it.
    require_once get_template_directory() . '/class-wp-bootstrap-navwalker.php';
}

You will also need to declare a new menu in your functions.php file if one doesn't already exist.

register_nav_menus( array(
    'primary' => __( 'Primary Menu', 'THEMENAME' ),
) );

Usage

Add or update any wp_nav_menu() functions in your theme (often found in header.php) to use the new walker by adding a 'walker' item to the wp_nav_menu args array.

wp_nav_menu( array(
    'theme_location'  => 'primary',
    'depth'           => 2, // 1 = no dropdowns, 2 = with dropdowns.
    'container'       => 'div',
    'container_class' => 'collapse navbar-collapse',
    'container_id'    => 'bs-example-navbar-collapse-1',
    'menu_class'      => 'navbar-nav mr-auto',
    'fallback_cb'     => 'WP_Bootstrap_Navwalker::fallback',
    'walker'          => new WP_Bootstrap_Navwalker(),
) );

Your menu will now be formatted with the correct syntax and classes to implement Bootstrap dropdown navigation.

Typically the menu is wrapped with additional markup, here is an example of a fixed-top menu that collapse for responsive navigation at the md breakpoint.

<nav class="navbar navbar-expand-md navbar-light bg-light" role="navigation">
  <div class="container">
    <!-- Brand and toggle get grouped for better mobile display -->
    <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-controls="bs-example-navbar-collapse-1" aria-expanded="false" aria-label="<?php esc_attr_e( 'Toggle navigation', 'your-theme-slug' ); ?>">
        <span class="navbar-toggler-icon"></span>
    </button>
    <a class="navbar-brand" href="#">Navbar</a>
        <?php
        wp_nav_menu( array(
            'theme_location'    => 'primary',
            'depth'             => 2,
            'container'         => 'div',
            'container_class'   => 'collapse navbar-collapse',
            'container_id'      => 'bs-example-navbar-collapse-1',
            'menu_class'        => 'nav navbar-nav',
            'fallback_cb'       => 'WP_Bootstrap_Navwalker::fallback',
            'walker'            => new WP_Bootstrap_Navwalker(),
        ) );
        ?>
    </div>
</nav>

To change your menu style add Bootstrap nav class names to the menu_class declaration.

Review options in the Bootstrap docs for more information on nav classes.

Displaying the Menu

To display the menu you must associate your menu with your theme location. You can do this by selecting your theme location in the Theme Locations list while editing a menu in the WordPress menu manager.

Making this Walker the Default Walker for Nav Menus

There has been some interest in making this walker the default walker for all menus. That could result in some unexpected situations but it can be achieved by adding this function to your functions.php file.

function prefix_modify_nav_menu_args( $args ) {
    return array_merge( $args, array(
        'walker' => new WP_Bootstrap_Navwalker(),
    ) );
}
add_filter( 'wp_nav_menu_args', 'prefix_modify_nav_menu_args' );

Simply updating the walker may not be enough to get menus working right, you may need to add wrappers or additional classes, you can do that via the above function as well.

Usage with Bootstrap 5

Bootstrap 5 uses namespaced data attributes. All data attributes now include bs as an infix. The new attributes work just like the old ones. Here’s the menu toggle button from the example above with the renamed data attributes.

<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#bs-example-navbar-collapse-1" aria-controls="bs-example-navbar-collapse-1" aria-expanded="false" aria-label="<?php esc_attr_e( 'Toggle navigation', 'your-theme-slug' ); ?>">
    <span class="navbar-toggler-icon"></span>
</button>

The walker also adds a data attribute for dropdown toggles via the start_el() method. Paste this to your functions.php to make the walker use the infixed data attibute.

add_filter( 'nav_menu_link_attributes', 'prefix_bs5_dropdown_data_attribute', 20, 3 );
/**
 * Use namespaced data attribute for Bootstrap's dropdown toggles.
 *
 * @param array    $atts HTML attributes applied to the item's `<a>` element.
 * @param WP_Post  $item The current menu item.
 * @param stdClass $args An object of wp_nav_menu() arguments.
 * @return array
 */
function prefix_bs5_dropdown_data_attribute( $atts, $item, $args ) {
    if ( is_a( $args->walker, 'WP_Bootstrap_Navwalker' ) ) {
        if ( array_key_exists( 'data-toggle', $atts ) ) {
            unset( $atts['data-toggle'] );
            $atts['data-bs-toggle'] = 'dropdown';
        }
    }
    return $atts;
}

Menu Caching

On some sites generating a large menu that rarely ever changes on every page request is an overhead that you may want to avoid. In those cases I can suggest you look at storing menu results in a transient.

The biggest drawback to caching nav menus with this method is that it cannot easily apply the .current-menu-item or the .active class to the currently active item as WP decides what is currently active on page load - and since the menu is cached it only knows the active page that it was cached on originally.

You can decide yourself if you want to put up with those drawbacks for the benefit of removing the menu generation time on most page loads. You can follow this article by Dave Clements to see how we cached nav menus that were generated by this walker: https://www.doitwithwp.com/use-transients-speed-wordpress-menus/

Be sure to set the echo argument to FALSE in the wp_nav_menu() call when doing this so that the results can be stored instead of echoed to the page.

See also:

Extras

This script included the ability to use Bootstrap nav link mods in your menus through the WordPress menu UI. Disabled links, dropdown headers and dropdown dividers are supported. Additionally icon support is built-in for Glyphicons and Font Awesome (note: you will need to include the icon stylesheets or assets separately).

Icons

To add an Icon to your link simply enter Glyphicons or Font Awesome class names in the links CSS Classes field in the Menu UI and the walker class will do the rest. IE glyphicons glyphicons-bullhorn or fa fa-arrow-left or fas fa-arrow-left.

Icon-Only Items

To make an item appear with the icon only apply the bootstrap screen reader class sr-only to the item alongside any icon classnames. This will then hide only the text that would appear as the link text.

Disabled Links

To set a disabled link simply add disabled to the CSS Classes field in the Menu UI and the walker class will do the rest. Note: In addition to adding the .disabled class this will change the link href to # as well so that it is not a follow-able link.

Dropdown Headers, Dropdown Dividers & Dropdown Item Text

Headers, dividers and text only items can be added within dropdowns by adding a Custom Link and adding either dropdown-header, dropdown-divider or dropdown-item-text into the CSS Classes input. Note: This will remove the href on the item and change it to either a <span> for headers or a <div> for dividers.

Missing Edit Shortcut in Customizer Preview

According to the documentation for wp_nav_menu() one has to provide an instance of the custom walker class in order to apply the custom walker to the menu. As the instance is not JSON serializable this will cause the menu edit shortcut to not appear in the Customizer preview. To fix this do the following:

  1. Provide the class name string instead of the class instance as value for the 'walker' key in the array of wp_nav_menu's arguments,
wp_nav_menu( array(
    'theme_location'  => 'primary',
    'depth'           => 2, // 1 = no dropdowns, 2 = with dropdowns.
    'container'       => 'div',
    'container_class' => 'collapse navbar-collapse',
    'container_id'    => 'bs-example-navbar-collapse-1',
    'menu_class'      => 'navbar-nav mr-auto',
    'fallback_cb'     => 'WP_Bootstrap_Navwalker::fallback',
-    'walker'          => new WP_Bootstrap_Navwalker(),
+    'walker'          => 'WP_Bootstrap_Navwalker',
) );
  1. re-add the class instance by adding this filter to your functions.php
function slug_provide_walker_instance( $args ) {
    if ( isset( $args['walker'] ) && is_string( $args['walker'] ) && class_exists( $args['walker'] ) ) {
        $args['walker'] = new $args['walker'];
    }
    return $args;
}
add_filter( 'wp_nav_menu_args', 'slug_provide_walker_instance', 1001 );

Changelog

Please see the Changelog.

wp-bootstrap-navwalker's People

Contributors

amostajo avatar bhubbard avatar bikubi avatar billoosijok avatar bitdeli-chef avatar braydengray416 avatar burjulius avatar claudiosanches avatar cvrebert avatar davegaeddert avatar dependabot-preview[bot] avatar iandelmar avatar jakewhiteley avatar kentr avatar mafuba avatar maghffu avatar ousid avatar pattonwebz avatar planbrewski avatar sfgarza avatar szepeviktor avatar tomjn avatar zebedeu avatar zethzeth avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

wp-bootstrap-navwalker's Issues

REAME.md #navbar-fixed-top

The working code example doesn't need to be enclosed in PHP tags seeing as it's HTML with PHP used inline. Copying and pasting this example into a theme verbatim will throw and error or two.

iPad (and iOS devices?) needs href

Hello,

I had to add :

$attributes .= ! empty( $item->url ) ? ' href="' . esc_attr( $item->url ) .'"' : '';
// FOR IPAD
$attributes .= empty( $item->url ) ? ' href="#"' : '';

in start_el function, because drop downs will not work on an "a" element without an href attribute declared, on an iPad 1 with iOS 5.1.1.

Warning/Errors upon upgrade to 3.6

Getting the following messages after upgrading to 3.6:

Strict Standards: Declaration of wp_bootstrap_navwalker::start_lvl() should be compatible with Walker::start_lvl(&$output, $depth = 0, $args = Array) in wp_bootstrap_navwalker.php on line 143

Warning: Cannot modify header information - headers already sent by (output started at wp_bootstrap_navwalker.php:143) in wp-includes/option.php on line 571

Warning: Cannot modify header information - headers already sent by (output started at wp_bootstrap_navwalker.php:143) in wp-includes/option.php on line 572

add brand for the first element

Hello and thank you for your great custom navbar, it helped me a lot.
I'm just wondering if it's possible to add the brand tag for the first element.
How can i do that?

Fix Multi Level Bootstrap Menu and Open on Mouse Hover

Thanks for awesome work,
A. but there's an issue in multi level menu (it's not open) ..
replace line:
if($args->has_children) { $class_names .= ' dropdown'; }
with:
if($args->has_children && $depth === 0) { $class_names .= ' dropdown'; } elseif($args->has_children && $depth > 0) { $class_names .= ' dropdown-submenu'; }

B. Hover Dropdown Menu
To open menu on hover use (bootstrap-hover-dropdown.js) from (CWSpear) and ..
replace line:
$atts['data-toggle'] = 'dropdown';
with:
$atts['data-hover'] = 'dropdown';

and thanks again for your work and your time .. hope to help

Dividers

The word "Divider" has to be in the "Title Attribute" field or else it won't work.
The code seems to say the same thing:

Line 49: $item->attr_title, 'divider'

Therefore, the documents should say:

...a Link Text or Title Attribute of divider...

Flat menu's getting wrong class

Superb class you have here. Worked wonders for my theme.
There's a problem however when I request a menu with a depth of 1. A menu item with sub items still shows the down arrow icon and doesn't link to the page.
For instance if I have:
/our-company
--> /history
--> /staff
etc. the main menu works great but I have another call to that menu in the footer that's flat. The our-company link should link to the parent page instead of do nothing.

I can of course create a separate menu in the admin but thought I'd point this out.

Multilevel Dropdown

Hello. There's something that has been boggling my mind a bit and that is multilevel dropdowns. I've never really needed it before but now that i am building an online store for a retail company and I need 3-4 levels. I've looked around but have only found CSS alternatives that don't work in mobile. I know this may be a more bootstrappy question but I figured that it would be something nice to add to your nav walker. What are your thoughts on this?

Works on local, but not online

I'm currently using wp-bootstrap-navwalker for a customized navigator for my bootstrap/wordpress website. It worked well locally using MAMP, but once I uploaded the theme and activate it on the online wordpress, I get the following errors:


Warning: Missing argument 2 for register_nav_menu(), called in /mnt/web5/c0/58/51640958/htdocs/adam/wp-content/themes/Adam/functions.php on line 178 and defined in /mnt/web5/c0/58/51640958/htdocs/adam/wp-includes/nav-menu.php on line 106

Warning: Illegal offset type in /mnt/web5/c0/58/51640958/htdocs/adam/wp-includes/nav-menu.php on line 107

Warning: Cannot modify header information - headers already sent by (output started at /mnt/web5/c0/58/51640958/htdocs/adam/wp-includes/nav-menu.php:106) in /mnt/web5/c0/58/51640958/htdocs/adam/wp-includes/option.php on line 571

Warning: Cannot modify header information - headers already sent by (output started at /mnt/web5/c0/58/51640958/htdocs/adam/wp-includes/nav-menu.php:106) in /mnt/web5/c0/58/51640958/htdocs/adam/wp-includes/option.php on line 572

The lines stated in nav-menu.php is as followed:

function register_nav_menu( $location, $description ) {
    register_nav_menus( array( $location => $description ) );
}

I'm not sure what the issue is.. I assume it has something to do with wordpress not able to register the navigator or something in that direction... how do I go about fixing this?

// EDIT:

Code in my functions.php:

function register_menus() {
    register_nav_menu( array('top_menu' => 'Top menu')
    );
}

And header.php:

<?php 
                    wp_nav_menu( array(
                        'menu'       => 'top_menu',
                        'depth'      => 2,
                        'container'  => false,
                        'menu_class' => 'nav',
                        'fallback_cb' => 'wp_page_menu',
                        //Process nav menu using our custom nav walker
                        'walker' => new wp_bootstrap_navwalker())
                    );
                ?>

child theme support

Did something similar, then tried with your class as well.

Seems if you define the class in a parent themes functions.php, then enable a child theme of that parent with nothing fancy except the child style.css. All the nav items are empty.

Curious if you know why?

Menu attribute is being added to <span class="glyphicon...

It seems the plugin is hijacking the title attribute (the field you can edit in the menu structure admin).

For instance if I add "Find out more about our services" to a menu item named "About" the source looks like this:

<a href="http://mysite.com/about/" title="About">
<span class="glyphicon Find out more about our services"></span>
 About
</a>

Also the navigation label ends up in the title attribute.

Ideally the mark up should look like this:

<a href="http://mysite.com/about/" title="Find out more about our services">
<span class="glyphicon"></span>
 About
</a>

Ability to use "dropup" class for menu items with submenus

I've tried to use the "theme_location" argument to change "dropdown" class by "dropup" but I get the following error when "theme_location" is specified:

Notice: Trying to get property of non-object in /path/to/wp_bootstrap_navwalker.php on line 67

It would be great for footer menus.

Caret in Submenu

Hi,

I used your navwalker and found that in submenu which has items, there's an caret which make it double carets (▼ and ►).
double caret

navbar is hide when we are login

there is wordpress admin navbar which help as navigate between public site and admin area but when we use fixed top navigation class our navbar is at the backside of wordpress nav bar how to fix that problem.

and thank's from your nice work.

Dropdown clicks not working

First of all, I don't know if this is something related to the theme I'm developing, your script or any other thing.

I'm using this script to implement a Bootstrap theme in Wordpress. Everything works fine in the menus, except the click on the one that have submenus. When I click it, the "open" class is not added to the 'li class="dropdown"' part.

I have done everything according to the instructions in this repository, but this is not working. I can't tell if it's related to this or any Javascript bits.

Best regards;
Bruno Miguel

Customized to Bootstrap 3 RC2

Hi, have changed the code to work with version 3 RC 2. Here it is:

/**

class wp_bootstrap_navwalker extends Walker_Nav_Menu {

/**
 * @see Walker::start_lvl()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param int $depth Depth of page. Used for padding.
 */
function start_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat( "\t", $depth );
    $output    .= "\n$indent<ul class=\"dropdown-menu\">\n";        
}

/**
 * @see Walker::start_el()
 * @since 3.0.0
 *
 * @param string $output Passed by reference. Used to append additional content.
 * @param object $item Menu item data object.
 * @param int $depth Depth of menu item. Used for padding.
 * @param int $current_page Menu item ID.
 * @param object $args
 */

function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    global $wp_query;
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    /**
     * Dividers & Headers
     * ==================
     * Determine whether the item is a Divider, Header, or regular menu item.
     * To prevent errors we use the strcasecmp() function to so a comparison
     * that is not case sensitive. The strcasecmp() function returns a 0 if 
     * the strings are equal.
     */
    if (strcasecmp($item->title, 'divider') == 0) {
        // Item is a Divider
        $output .= $indent . '<li class="divider">';
    } else if (strcasecmp($item->title, 'divider-vertical') == 0) {
        // Item is a Vertical Divider
        $output .= $indent . '<li class="divider-vertical">';
    } else if (strcasecmp($item->title, 'dropdown-header') == 0) {
        // Item is a Header
        $output .= $indent . '<li class="dropdown-header">' . esc_attr( $item->attr_title );
    } else {

        $class_names = $value = '';
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $classes[] = ($item->current) ? 'active' : '';
        $classes[] = 'menu-item-' . $item->ID;
        $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );

        if ($args->has_children && $depth > 0) {
            $class_names .= ' dropdown-submenu';
        } else if($args->has_children && $depth === 0) {
            $class_names .= ' dropdown';
        }

        $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

        $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
        $id = $id ? ' id="' . esc_attr( $id ) . '"' : '';

        $output .= $indent . '<li' . $id . $value . $class_names .'>';

        $attributes = ! empty( $item->target )     ? ' target="' . esc_attr( $item->target     ) .'"' : '';
        $attributes .= ! empty( $item->xfn )        ? ' rel="'    . esc_attr( $item->xfn        ) .'"' : '';
        $attributes .= ! empty( $item->url )        ? ' href="'   . esc_attr( $item->url        ) .'"' : '';
        $attributes .= ($args->has_children)        ? ' data-toggle="dropdown" class="dropdown-toggle"' : '';

        $item_output = $args->before;

        /**
         * Glyphicons
         * ===========
         * Since the the menu item is NOT a Divider or Header we check the see
         * if there is a value in the attr_title property. If the attr_title
         * property is NOT null we apply it as the class name for the glyphicon.
         */
        if(! empty( $item->attr_title )){
            $item_output .= '<a'. $attributes .'><i class="' . esc_attr( $item->attr_title ) . '"></i>&nbsp;';
        } else {
            $item_output .= '<a'. $attributes .'>';
        }

        $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
        $item_output .= ($args->has_children && $depth == 0) ? ' <b class="caret"></b></a>' : '</a>';
        $item_output .= $args->after;

        $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
    }
}

/**
 * Traverse elements to create list from elements.
 *
 * Display one element if the element doesn't have any children otherwise,
 * display the element and its children. Will only traverse up to the max
 * depth and no ignore elements under that depth. 
 *
 * This method shouldn't be called directly, use the walk() method instead.
 *
 * @see Walker::start_el()
 * @since 2.5.0
 *
 * @param object $element Data object
 * @param array $children_elements List of elements to continue traversing.
 * @param int $max_depth Max depth to traverse.
 * @param int $depth Depth of current element.
 * @param array $args
 * @param string $output Passed by reference. Used to append additional content.
 * @return null Null on failure with no changes to parameters.
 */

function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
    if ( !$element ) {
        return;
    }

    $id_field = $this->db_fields['id'];

    //display this element
    if ( is_object( $args[0] ) ) {
       $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
    }

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

}

You have to use "dropdown-header" for headers.

Thanks!!!

IE 8 only shows Collapsed Mode

I'm having a strange issue in IE8 where the menu is only showing up in the collapsed mode. I can click the button, and it expands to show the menu items, and they work - but the normal menu view is not working, even when the page is expanded to full screen.
I am wondering if anybody else has had this issue.

Support for sub-headings

Thank you for making this available! It really helped me out.

You included functionality for the dividers (thank you!) but not the sub-headings, as far as I can tell. I ended up adding that functionality myself, in case anyone else would be interested in what I did.

I changed this if statement:
if (strcasecmp($item->title, 'divider') && strcasecmp($item->title, 'heading')) {

And the else statement:
} elseif (strcasecmp($item->title, 'heading')) { /* it's a divider */ $output .= $indent . '<li class="divider">'; } else { /* it's a sub-heading */ $output .= $indent . '<li class="nav-header">' . esc_attr( $item->attr_title ); }

Then you can use the headings by putting the word heading in the menu item label and the actual heading text in the title attribute.

This seems to be working for me, however, I'm no expert, so there may be a better way. But this may help someone out, so I wanted to share it.

Cheers!

Ability to have dropdown be split button eg link / caret

On sites like Font Awesome, their main nav functions like this:

  1. The parent links are all clickable to a primary page, eg "icons" just goes to the icons page
  2. The dropdowns are activated by clicking the caret.

Example of the split button: http://getbootstrap.com/components/#btn-dropdowns-split

This would be a great addition, I am guessing though it would have to be specified somehow as there's no way to know if it should build the standard dropdown, or a split button.

I am no PHP programmer, so while I can help with bootstrap html/css, making it actually work is out of my reach /cry. I am happy to take part in trying ot make this a feature though and plan to experiment with it a bit and see if I can at least run in to some useful errors.

Please respond here if you have more questions on my use case.

screen shot 2013-11-26 at 10 44 17 am

Parent clickable and mobile expanded

How can i make the parant clickable? now the parent has the link # and when in mobile every thing should be expanded so i can see parents children and be able to click parent in mobile?

is that possible?

Buttons

Any thoughts on adding button functionality (button dropdowns etc.)?

The new version (2.0.1) doesn't work for me

This bug happens on Wordpress 3.6
screenshot from 2013-08-30 23 08 44

Please take a look at my screenshot. The problem here is wp_nav_menu generate div class="nav navbar-nav" instead of ul class="nav navbar-nav". Here is the full html :
screenshot from 2013-08-30 23 09 12

and here is my header.php :
screenshot from 2013-08-30 23 09 25

Wrong parent being marked active

The navwalker is working very well, however I am having a problem with an incorrect menu item being marked as active. I'm using the Events Manager plugin, which stores events as custom post types.

When I view a single event, the page currently selected as the 'posts page' is marked as active. Could you give me a hint as to how to troubleshoot this? Thanks.

EDIT: Sorry, I've managed to figure out that it's not a navwalker issue!

display_element should call parent

Hello,

I think (in order to promote code reuse and avoid compatability issues) display_element should just make the check for children elements and then return control to the parent class. So something like (sorry, I was to lazy to make a pull request):

function display_element( $element, &$children_elements, $max_depth, $depth, $args, &$output ) {
        if ( !$element )
            return;

        $id_field = $this->db_fields['id'];

        //display this element
        if ( is_object( $args[0] ) )
           $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );

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

Downdown On First Menu Item Only

I tried to implement your menu dropdowns. However, the submenu appears only on first nav item. The dev site is here: http://dev.riverroadcoffees.com/
I've attached a screenshot of the wordpress menu. I've copied and pasted everything exactly from the main page. Any help would be appreciated. Thanks.
screen shot 2013-10-23 at 11 59 39 am

_EDIT_*
ALL the dropdowns show when i'm logged into wordpress. However, when not logged in, the don't appear.

How can I change color of navbar

I want to change the color of navbar how can i do that there is just two color navbar-inverse and the default one but i want to have orange color.

Not working when menu does not exists

I want to show the pages if there is no menu selected but I get some errors starting at line 48.
Notice: Trying to get property of non-object in C:\xampp\htdocs\wp-content\themes\the_theme\inc\twitter_bootstrap_nav_walker.class.php on line 48

I'm using WP 3.5.1

Active Menu Issue

I tried to use Post Category into the Menu and while reading a post, its category does not gets selected (active class) into the menu.

Caret are added in the last depth level too

Bootstrap 3.0 (and this walker as a consequence) supports only 2 levels deep menus. The problem is that there isn't any check on menu $depth to avoid the class adding carets in the last available level.

Please fix this.

How to keep the submenu opened when clicking thru submenu voices

hi,
first and foremost thanks for your great code.
My problem is: i open a submenu, i click on the submenu voice and then when the page is reloaded the submenu is closed again, but i'd need to keep that submenu opened . I'd need to fix this as my customer asked me for a horizontal submenu - which i achieved via css.

My menu code is this:
http://pastebin.com/DNybHXmC

(the backup query is there for other purposes...)

how can i achieve the aforementioned result?
thanks in advance for your reply :)

Divider element inserting extra <li>

Hi

I've noticed that when I add a divider element to the menu, the output contains an extra </li> and messes up the layout, not to mention a validation error.

Here's a shot of the menu structure:
Capture

Here's the output:

<nav class="pull-right dropdown">
    <ul id="menu-main" class="nav nav-pills">
        <li id="menu-item-88" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-88 dropdown">
            <a href="" data-toggle="dropdown"
            data-target="#" class="dropdown-toggle"> <span class="caret"></span>
            </a>
            <ul class="dropdown-menu">
                <li id="menu-item-84" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-84">
                    <a href=""></a>
                </li>
                <li class="divider"></li>
        </li>
        <li id="menu-item-147" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-147">
            <a href=""></a>
        </li>
        <li id="menu-item-236" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-236">
            <a href=""></a>
        </li>
        <li id="menu-item-295" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-295">
            <a href=""></a>
        </li>
        </ul>
        </li>
        <li id="menu-item-72" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-72">
            <a href=""></a>
        </li>
        <li id="menu-item-66" class="highlight menu-item menu-item-type-post_type menu-item-object-page menu-item-66">
            <a href=""></a>
        </li>
    </ul>
</nav>

Now according to the W3C validator, the </li> just before <li id="menu-item-72"> is and "end tag for element "LI" which is not open."

When I remove the Divider from the Wordpress menu, the validation error is gone. I've never really understood how the Walker works, so I have no clue what's going on here - any advice?

Thanks!

Multi-level?

Anything specific I need to do for multi-level menus? My menu can sometimes be 3 levels deep, but this walker seems to be stuck at 2.

Bug with WP 3.8 ???

Hi
I've test this class with WP 3.6 and 3.7 successfully but now it's seems to have some trouble to generate correctly the menu with WP 3.8 :

  • container_class and container_id is missing
  • All item is empty like
    • ......

Dropdown not working

Hi,

I can able to view the dropdown icon. But on hover or click the sub menu is not opening. Could you please guide me how to do that.

Dropdown not working (upon click) in Bootstrap 3.0.3

Sorry to bring up a closed issue, but the dropdown is not working (upon click) with Bootstrap 3.0.3 for me either. Dropdown js is already included in bootstrap.js, and all js loads fine.
Any suggestions? I really appreciate it.

(Didn't have this problem in previous 3.0-versions.)

2nd level not working on iPhone

On my installation the 2nd level doesn't work. When expanding the first level dropdown the page reloads (it seems) and the menu isn't clickable. When clicking the menu collapse and the 1st level links are clickable again. See test URL: http://bok.hoi.se/menu-bug

Adding a navform to the walker class

This walker class class is awesome!

Is there a way to add a nav-form to this code in the following way ?

[nav]
[div]
WALKER CLASS LIST GENERATED NAV LIST
include ('searchform-navbar.php');
[/div]
[/nav]

Big changes on the road to 3.0

Introduction

I have been blown away with the popularity of wp-bootstrap-navwalker and the people contributing to the project. Originally, wp-bootstrap-navwalker was built to serve my specific development needs and solve the simple problem of adding Bootstrap menus to WordPress.

As usage grows, so do the feature requests. To this point I have been reluctant to add additional features in an effort to keep things simple but I do think there is value in creating so complimentary add-ons to introduce more features. To achieve this I will be doing a complete rewrite.

The Plan

The plan is to create a modular walker framework that achieves the base functionality needed to implement Bootstrap 3.0 menus with extensibility to create add-on modules.

The add-on modules will be disabled by default and can be turned on by calling a public function similar to this:

if ( class_exists( 'WP_Bootstrap_Navwalker' ) ) {
    WP_Bootstrap_Navwalker::add_addon_support( array( 
        'multi-level-dropdown',
        'nav-list' )
    );
}

This way we avoid loading additional bloat into our sites while adding additional featured to the mix. Right away I see addons for multi level dropdowns, and abstracting the glyphicons functionality to an add-on aswell.

Two Pronged Solution

The ideal situation is to develop this as a drop in library for theme developers to integrate into their theme or framework. Aswell as a plugin where you can turn on and off individual framework options.

The beauty of taking the time to also create a plugin is this will also give us utility classes needed to easily add the framework options to our themes as well.

Technical Considerations

Ideally this would be achieved while adding the least additional HTTP requests as possible. Understanding that some add-ons may require additional .less & .js files I think it is important to compile and minify all of out resources into single .css & .js files.

This is a large consideration that may be difficult to achieve, although with libraries like Grunt this may be possible. I think its worth taking a look at and may be a plugin of its own. I would love a plugin that would take all of the .less, .css & .js files from my theme/plugins and package and minify them nicely.

Yes, this would be beautiful.

if ( class_exists( 'Gruntify' ) ) {
    Gruntify::add_less( array( 
        '../less/style.less' )
    );
        Gruntify::add_js( array( 
        '../js/awesomeness.js' )
    );
} else {
      // Enqueue normally
}

Feedback

I would love to know what you all think about this direction.

Especially you amazing contributors:
@claudiosmweb
@mindctrl
@pattonwebz
@cvrebert
@mafuba
@wboptimise
@mharis

collapse wont work properly

I noticed that after i expand the collapsable menu (in the small and extra small screen) it wont collapse again if i click on the button

is that a known issue or i'm doing something wrong?

P.

Strict Standards Error bootstrap navwalker

Hi there

Just thought I should bring these issues to your attention.

I've been trying this in a theme but I got the following error:

Strict Standards: Declaration of wp_bootstrap_navwalker::start_lvl() should be compatible with Walker_Nav_Menu::start_lvl(&$output, $depth = 0, $args = Array) in .../wp-content/themes/flat-portfolio/wp_bootstrap_navwalker.php on line 143

I was told on WordPress Answers that It means:

It means that the declaration of the start_lvl method in wp_bootstrap_navwalker should match the declaration of the method in Walker_Nav_Menu. It doesn't.

function start_lvl( &$output, $depth ) {
VS.

function start_lvl( &$output, $depth = 0, $args = array() ) {
Make the arguments match exactly and you should be fine.

Also I get Notice: Trying to get property of non-object errors with wp-debug set to true if the menu is not set. Please let me know how I can fix this.

Thanks and best

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.