SideNav for WordPress - Menu Walker


Topic: SideNav for WordPress - Menu Walker

pavelsemiklit pro asked 7 years ago

I'm trying to get a menu setup for WordPress for Side Nav, but the menu walker supplied in the WordPress tutorial not allowing me to make it work properly. Do you a tutorial for side nav for WordPress?

Sebastian Kaczmarek staff pro premium commented 7 years ago

Hi Pavel, What exactly do you mean by "not working properly"? Could you please provide us with more specific information? Regards, Sebastian

pavelsemiklit pro commented 7 years ago

Hi Sebastian, I've tried to use the menu walker and with the sidenav it would not display menu properly like the walker was not meant to be used for sidenavs. For example: wrong divs and wrappers would comes so the menu looks nothing like menu used on this site in sidenav.

Sebastian Kaczmarek staff pro premium answered 7 years ago

Hi Pavel,

The menu walker presented in the tutorial is designed to work with the navbar. If you want to create a SideNav menu walker you have to modify the walker from the tutorial a little bit because the SideNav is made of different HTML tags. Example implementation could look like this:

class Sidenav_Menu_Walker extends Walker {

  public $tree_type = array( 'post_type', 'taxonomy', 'custom' );

  public $db_fields = array( 'parent' => 'menu_item_parent', 'id' => 'db_id' );

  public function start_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat("\t", $depth);
    $output .= "\n$indent <div class=\"collapsible-body\"> <ul class=\"sub-menu\">n";
  }

  public function end_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat("\t", $depth);

    $output .= "$indent</ul></div>\n";
  }

  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_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {

    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';

    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    $classes[] = ' menu-item-' . $item->ID;

    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args, $depth ) );
    $class_names = $class_names ? ' class="' . esc_attr( $class_names ) . '"' : '';

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

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

    $atts = array();
    $atts['title']  = ! empty( $item->attr_title ) ? $item->attr_title : '';
    $atts['target'] = ! empty( $item->target )     ? $item->target     : '';
    $atts['rel']    = ! empty( $item->xfn )        ? $item->xfn        : '';
    $atts['href']   = ! empty( $item->url )        ? $item->url        : '';

    $atts = apply_filters( 'nav_menu_link_attributes', $atts, $item, $args, $depth );

    $attributes = '';
    foreach ( $atts as $attr => $value ) {
      if ( ! empty( $value ) ) {
        $value = ( 'href' === $attr ) ? esc_url( $value ) : esc_attr( $value );
        $attributes .= ' ' . $attr . '="' . $value . '"';
      }
    }

    $active = ($item->current || $item->current_item_ancestor) ? 'active' : '';

    $item_output = $args->before;
    if ($args->has_children ) {
      $item_output .= '<a class="collapsible-header waves-effect arrow-r '.$active.'">';
    }else {
      $item_output .= '<a class="collapsible-header waves-effect"' . $link_id . ' '. $attributes .'>';
    }
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    if ($args->has_children ) {
      $item_output .= '<i class="fa fa-angle-down rotate-icon"></i></a>';
    }else {
      $item_output .= '</a>';
    }

    $item_output .= $args->after;

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

  public function end_el( &$output, $item, $depth = 0, $args = array() ) {

    $output .= "</li>\n";

  }

}

And to use it, you have to write something like this:

$args = array(
    'theme_location'  => 'primary',
    'container'       => 'false',
    'echo'            => true,
    'menu_class'      => 'collapsible collapsible-accordion',
    'menu_id'         => 'side-menu',
    'fallback_cb'     => 'wp_page_menu',
    'walker'          => new Sidenav_Menu_Walker()
);
wp_nav_menu( $args );

When you refresh the page you should see your awesome sidenav.

Regards,
Sebastian


Sebastian Kaczmarek staff pro premium commented 7 years ago

Hi, From the technical point of view, it is possible of course. Unfortunately, our MDB Sidenav does not support more than 2 levels of nesting. Regards, Sebastian

pavelsemiklit pro commented 7 years ago

Hi Sebastian, Is there any news regarding my last comment? Thank you Pavel

pavelsemiklit pro commented 7 years ago

Hi Sebastian, Just saw this message, thanks, this is unfortunate.

Please insert min. 20 characters.

FREE CONSULTATION

Hire our experts to build a dedicated project. We'll analyze your business requirements, for free.

Status

Answered

Specification of the issue
  • User: Pro
  • Premium support: No
  • Technology: General Bootstrap questions
  • MDB Version: -
  • Device: -
  • Browser: -
  • OS: -
  • Provided sample code: No
  • Provided link: No