Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
A WordPress Navigation Walker that adds a clean BEM CSS Structure
<?php
namespace HelloTheme;
class NavWalker extends \Walker_Nav_Menu {
public $css_base = 'menu';
public function __construct( $base = '' ) {
if ( '' != $base ) {
$this->css_base = $base;
}
}
public function display_element( $element, &$children_elements, $max_depth, $depth = 0, $args, &$output ) {
$id_field = $this->db_fields['id'];
if ( is_object( $args[0] ) ) {
$args[0]->has_children = ! empty( $children_elements[ $element->$id_field ] );
}
return parent::display_element( $element, $children_elements, $max_depth, $depth, $args, $output );
}
public function start_lvl( &$output, $depth = 0, $args = array() ) {
$real_depth = $depth + 1;
$indent = str_repeat( "\t", $real_depth );
$prefix = $this->css_base;
$classes = [
"{$prefix}",
"{$prefix}--level-{$real_depth}",
];
$output .= "\n" . $indent . '<ul class="' . implode( ' ', $classes ) . '">' . "\n";
}
// Add main/sub classes to li's and links
public function start_el( &$output, $item, $depth = 0, $args = [], $id = 0 ) {
global $wp_query;
$indent = ( $depth > 0 ? str_repeat( ' ', $depth ) : '' );
$prefix = $this->css_base;
/**
* Item
*/
$item_classes = [];
$item_classes['item_class'] = "{$prefix}__item";
if ( $args->has_children ) {
$item_classes['parent_class'] = "{$prefix}__item--has-children";
}
if ( in_array( 'current-menu-item', $item->classes ) ) {
$item_classes['active_page_class'] = "{$prefix}__item--active";
}
if ( in_array( 'current-menu-parent', $item->classes ) ) {
$item_classes['active_parent_class'] = "{$prefix}__item--parent-active";
}
if ( in_array( 'current-menu-ancestor', $item->classes ) ) {
$item_classes['active_ancestor_class'] = "{$prefix}__item--ancestor-active";
}
if ( '' !== $item->classes[0] ) {
$item_classes['user_class'] = $item->classes[0];
}
// Attributes
$item_attributes = [];
$item_attributes['id'] = $prefix . '-item-' . $item->object_id;
if ( ! empty( $item_classes ) ) {
$item_attributes['class'] = implode( ' ', $item_classes );
}
array_walk( $item_attributes, 'esc_attr' );
// Markup
$item_markup = $indent;
$item_markup .= '<li';
foreach ( $item_attributes as $att => $value ) {
$item_markup .= " $att='$value'";
}
$item_markup .= '>';
/**
* Link
*/
$link_classes = [];
$link_classes[] = "{$prefix}__link";
// Attributes
$link_attributes = [];
if ( ! empty( $item->attr_title ) ) {
$link_attributes['title'] = $item->attr_title;
}
if ( ! empty( $item->target ) ) {
$link_attributes['target'] = $item->target;
}
if ( ! empty( $item->xfn ) ) {
$link_attributes['rel'] = $item->xfn;
}
if ( ! empty( $item->url ) ) {
$link_attributes['href'] = $item->url;
}
if ( ! empty( $link_classes ) ) {
$link_attributes['class'] = implode( ' ', $item_classes );
}
array_walk( $link_attributes, 'esc_attr' );
// Markup
$link_markup = $args->before;
$link_markup .= '<a';
foreach ( $link_attributes as $att => $value ) {
$link_markup .= " $att='$value'";
}
$link_markup .= '>';
$link_markup .= $args->link_before;
$link_markup .= apply_filters( 'the_title', $item->title, $item->ID );
$link_markup .= $args->link_after;
$link_markup .= '</a>';
$link_markup .= $args->after;
/**
* create markup
*/
$output .= $item_markup . apply_filters( 'walker_nav_menu_start_el', $link_markup, $item, $depth, $args );
return $output;
}
}
<ul id="menu-main-menu" class="menu">
<li id="menu-item-59" class="menu__item">
<a href="https://mysite.com/" class="menu__link">Home</a>
</li>
<li id="menu-item-7" class="menu__item">
<a href="https://mysite.com/news/" class="menu__link">News</a>
</li>
<li id="menu-item-2" class="menu__item menu__item--has-children menu__item--parent-active menu__item--ancestor-active">
<a href="https://mysite.com/beispiel-seite/" class="menu__link">Beispiel-Seite</a>
<ul class="menu menu--level-1">
<li id="menu-item-261" class="menu__item menu__item--active">
<a href="https://mysite.com/beispiel-seite/subseite/" class="menu__link">Subseite</a>
</li>
</ul>
</li>
</ul>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.