{"id":13660327,"url":"https://github.com/wp-bootstrap/wp-bootstrap-navwalker","last_synced_at":"2025-12-12T04:03:17.696Z","repository":{"id":4135741,"uuid":"5248178","full_name":"wp-bootstrap/wp-bootstrap-navwalker","owner":"wp-bootstrap","description":"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.","archived":false,"fork":false,"pushed_at":"2022-08-08T15:23:04.000Z","size":581,"stargazers_count":3369,"open_issues_count":35,"forks_count":1918,"subscribers_count":212,"default_branch":"master","last_synced_at":"2025-04-09T19:13:53.694Z","etag":null,"topics":["bootstrap","custom-theme","hacktoberfest","icons","menus","nav","navigation","php","twitter-bootstrap","walker","wordpress","wordpress-theme","wp-bootstrap-navwalker"],"latest_commit_sha":null,"homepage":"https://wp-bootstrap.github.io/wp-bootstrap-navwalker/","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wp-bootstrap.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2012-07-31T16:06:31.000Z","updated_at":"2025-03-27T12:02:35.000Z","dependencies_parsed_at":"2022-08-06T15:00:37.303Z","dependency_job_id":null,"html_url":"https://github.com/wp-bootstrap/wp-bootstrap-navwalker","commit_stats":null,"previous_names":["twittem/wp-bootstrap-navwalker"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-bootstrap%2Fwp-bootstrap-navwalker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-bootstrap%2Fwp-bootstrap-navwalker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-bootstrap%2Fwp-bootstrap-navwalker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-bootstrap%2Fwp-bootstrap-navwalker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wp-bootstrap","download_url":"https://codeload.github.com/wp-bootstrap/wp-bootstrap-navwalker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":251336400,"owners_count":21573189,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["bootstrap","custom-theme","hacktoberfest","icons","menus","nav","navigation","php","twitter-bootstrap","walker","wordpress","wordpress-theme","wp-bootstrap-navwalker"],"created_at":"2024-08-02T05:01:20.141Z","updated_at":"2025-12-12T04:03:17.359Z","avatar_url":"https://github.com/wp-bootstrap.png","language":"PHP","readme":"# WP Bootstrap Navwalker\n\n[![Code Climate](https://codeclimate.com/github/wp-bootstrap/wp-bootstrap-navwalker/badges/gpa.svg)](https://codeclimate.com/github/wp-bootstrap/wp-bootstrap-navwalker)\n[![Test Coverage](https://codeclimate.com/github/wp-bootstrap/wp-bootstrap-navwalker/badges/coverage.svg)](https://codeclimate.com/github/wp-bootstrap/wp-bootstrap-navwalker/coverage)\n[![Issue Count](https://codeclimate.com/github/wp-bootstrap/wp-bootstrap-navwalker/badges/issue_count.svg)](https://codeclimate.com/github/wp-bootstrap/wp-bootstrap-navwalker)\n[![Build Status](https://travis-ci.org/wp-bootstrap/wp-bootstrap-navwalker.svg?branch=master)](https://travis-ci.org/wp-bootstrap/wp-bootstrap-navwalker)\n[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/wp-bootstrap/wp-bootstrap-navwalker/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/wp-bootstrap/wp-bootstrap-navwalker/?branch=master)\n[![Code Coverage](https://scrutinizer-ci.com/g/wp-bootstrap/wp-bootstrap-navwalker/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/wp-bootstrap/wp-bootstrap-navwalker/?branch=master)\n[![Build Status](https://scrutinizer-ci.com/g/wp-bootstrap/wp-bootstrap-navwalker/badges/build.png?b=master)](https://scrutinizer-ci.com/g/wp-bootstrap/wp-bootstrap-navwalker/build-status/master)\n\n**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**\n\nA custom WordPress Nav Walker Class to fully implement the Bootstrap 4 navigation style in a custom theme using the WordPress built in menu manager.\n\n## NOTES\n\nThis 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.\n\n### WordPress.org Theme Compliance\n\n*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.\n\n### Upgrade Notes\n\nBetween 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: \u003chttps://github.com/wp-bootstrap/wp-bootstrap-navwalker/tree/v3-branch\u003e\n\nHere is a list of the most notable changes:\n\n- The filename has been changed and prefixed with `class-` to better fit PHP coding standards naming conventions.\n  - New Name: `class-wp-bootstrap-navwalker.php`\n  - Old Name: `wp-bootstrap-navwalker.php`\n- Icon and link modifier handling is now done through the `CSS Classes` menu item input instead of the `Title` input.\n- Icon only items are possible using icon classes in combination with the `sr-only` classname.\n\n## Installation\n\nPlace **class-wp-bootstrap-navwalker.php** in your WordPress theme folder `/wp-content/themes/your-theme/`\n\nOpen your WordPress themes **functions.php** file - `/wp-content/themes/your-theme/functions.php` - and add the following code:\n\n```php\n/**\n * Register Custom Navigation Walker\n */\nfunction register_navwalker(){\n\trequire_once get_template_directory() . '/class-wp-bootstrap-navwalker.php';\n}\nadd_action( 'after_setup_theme', 'register_navwalker' );\n```\n\nIf you encounter errors with the above code use a check like this to return clean errors to help diagnose the problem.\n\n```php\nif ( ! file_exists( get_template_directory() . '/class-wp-bootstrap-navwalker.php' ) ) {\n    // File does not exist... return an error.\n    return new WP_Error( 'class-wp-bootstrap-navwalker-missing', __( 'It appears the class-wp-bootstrap-navwalker.php file may be missing.', 'wp-bootstrap-navwalker' ) );\n} else {\n    // File exists... require it.\n    require_once get_template_directory() . '/class-wp-bootstrap-navwalker.php';\n}\n```\n\nYou will also need to declare a new menu in your `functions.php` file if one doesn't already exist.\n\n```php\nregister_nav_menus( array(\n    'primary' =\u003e __( 'Primary Menu', 'THEMENAME' ),\n) );\n```\n\n## Usage\n\nAdd 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.\n\n```php\nwp_nav_menu( array(\n    'theme_location'  =\u003e 'primary',\n    'depth'           =\u003e 2, // 1 = no dropdowns, 2 = with dropdowns.\n    'container'       =\u003e 'div',\n    'container_class' =\u003e 'collapse navbar-collapse',\n    'container_id'    =\u003e 'bs-example-navbar-collapse-1',\n    'menu_class'      =\u003e 'navbar-nav mr-auto',\n    'fallback_cb'     =\u003e 'WP_Bootstrap_Navwalker::fallback',\n    'walker'          =\u003e new WP_Bootstrap_Navwalker(),\n) );\n```\n\nYour menu will now be formatted with the correct syntax and classes to implement Bootstrap dropdown navigation.\n\nTypically 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.\n\n```php\n\u003cnav class=\"navbar navbar-expand-md navbar-light bg-light\" role=\"navigation\"\u003e\n  \u003cdiv class=\"container\"\u003e\n    \u003c!-- Brand and toggle get grouped for better mobile display --\u003e\n    \u003cbutton 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=\"\u003c?php esc_attr_e( 'Toggle navigation', 'your-theme-slug' ); ?\u003e\"\u003e\n        \u003cspan class=\"navbar-toggler-icon\"\u003e\u003c/span\u003e\n    \u003c/button\u003e\n    \u003ca class=\"navbar-brand\" href=\"#\"\u003eNavbar\u003c/a\u003e\n        \u003c?php\n        wp_nav_menu( array(\n            'theme_location'    =\u003e 'primary',\n            'depth'             =\u003e 2,\n            'container'         =\u003e 'div',\n            'container_class'   =\u003e 'collapse navbar-collapse',\n            'container_id'      =\u003e 'bs-example-navbar-collapse-1',\n            'menu_class'        =\u003e 'nav navbar-nav',\n            'fallback_cb'       =\u003e 'WP_Bootstrap_Navwalker::fallback',\n            'walker'            =\u003e new WP_Bootstrap_Navwalker(),\n        ) );\n        ?\u003e\n    \u003c/div\u003e\n\u003c/nav\u003e\n```\n\nTo change your menu style add Bootstrap nav class names to the `menu_class` declaration.\n\nReview options in the Bootstrap docs for more information on [nav classes](https://getbootstrap.com/components/#nav).\n\n### Displaying the Menu\n\nTo 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.\n\n### Making this Walker the Default Walker for Nav Menus\n\nThere 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.\n\n```php\nfunction prefix_modify_nav_menu_args( $args ) {\n    return array_merge( $args, array(\n        'walker' =\u003e new WP_Bootstrap_Navwalker(),\n    ) );\n}\nadd_filter( 'wp_nav_menu_args', 'prefix_modify_nav_menu_args' );\n```\n\nSimply 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.\n\n### Usage with Bootstrap 5\n\nBootstrap 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.\n\n```php\n\u003cbutton 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=\"\u003c?php esc_attr_e( 'Toggle navigation', 'your-theme-slug' ); ?\u003e\"\u003e\n    \u003cspan class=\"navbar-toggler-icon\"\u003e\u003c/span\u003e\n\u003c/button\u003e\n```\n\nThe 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.\n\n```php\nadd_filter( 'nav_menu_link_attributes', 'prefix_bs5_dropdown_data_attribute', 20, 3 );\n/**\n * Use namespaced data attribute for Bootstrap's dropdown toggles.\n *\n * @param array    $atts HTML attributes applied to the item's `\u003ca\u003e` element.\n * @param WP_Post  $item The current menu item.\n * @param stdClass $args An object of wp_nav_menu() arguments.\n * @return array\n */\nfunction prefix_bs5_dropdown_data_attribute( $atts, $item, $args ) {\n    if ( is_a( $args-\u003ewalker, 'WP_Bootstrap_Navwalker' ) ) {\n        if ( array_key_exists( 'data-toggle', $atts ) ) {\n            unset( $atts['data-toggle'] );\n            $atts['data-bs-toggle'] = 'dropdown';\n        }\n    }\n    return $atts;\n}\n```\n\n### Menu Caching\n\nOn 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.\n\nThe 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.\n\nYou 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: \u003chttps://www.doitwithwp.com/use-transients-speed-wordpress-menus/\u003e\n\nBe 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.\n\nSee also:\n\n- \u003chttps://generatewp.com/how-to-use-transients-to-speed-up-wordpress-menus/\u003e\n- \u003chttps://vip-svn.wordpress.com/plugins/cache-nav-menu/cache-nav-menu.php\u003e\n\n### Extras\n\nThis 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).\n\n#### Icons\n\nTo 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`.\n\n#### Icon-Only Items\n\nTo 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.\n\n#### Disabled Links\n\nTo 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._\n\n#### Dropdown Headers, Dropdown Dividers \u0026 Dropdown Item Text\n\nHeaders, 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 `\u003cspan\u003e` for headers or a `\u003cdiv\u003e` for dividers._\n\n### Missing Edit Shortcut in Customizer Preview\n\nAccording to the documentation for [`wp_nav_menu()`](https://developer.wordpress.org/reference/functions/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](https://make.wordpress.org/core/2015/07/29/fast-previewing-changes-to-menus-in-the-customizer/) this will cause the menu edit shortcut to not appear in the Customizer preview. To fix this do the following:\n1. 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,\n```diff\nwp_nav_menu( array(\n    'theme_location'  =\u003e 'primary',\n    'depth'           =\u003e 2, // 1 = no dropdowns, 2 = with dropdowns.\n    'container'       =\u003e 'div',\n    'container_class' =\u003e 'collapse navbar-collapse',\n    'container_id'    =\u003e 'bs-example-navbar-collapse-1',\n    'menu_class'      =\u003e 'navbar-nav mr-auto',\n    'fallback_cb'     =\u003e 'WP_Bootstrap_Navwalker::fallback',\n-    'walker'          =\u003e new WP_Bootstrap_Navwalker(),\n+    'walker'          =\u003e 'WP_Bootstrap_Navwalker',\n) );\n```\n2. re-add the class instance by adding this filter to your `functions.php`\n```php\nfunction slug_provide_walker_instance( $args ) {\n    if ( isset( $args['walker'] ) \u0026\u0026 is_string( $args['walker'] ) \u0026\u0026 class_exists( $args['walker'] ) ) {\n        $args['walker'] = new $args['walker'];\n    }\n    return $args;\n}\nadd_filter( 'wp_nav_menu_args', 'slug_provide_walker_instance', 1001 );\n```\n\n## Changelog\n\nPlease see the [Changelog](https://github.com/wp-bootstrap/wp-bootstrap-navwalker/blob/master/CHANGELOG.md).\n","funding_links":[],"categories":["PHP","Helper library, code snippet"],"sub_categories":["2. Sage"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwp-bootstrap%2Fwp-bootstrap-navwalker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwp-bootstrap%2Fwp-bootstrap-navwalker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwp-bootstrap%2Fwp-bootstrap-navwalker/lists"}