• Hello everyone! First of all sorry me for my bad English but isn’t my native language so I’ll do as best as possible to explain my problem.

    I want to create a custom menu with Walker_Nav_Menu that should look like this:

    +——–+——–+——–+
    | Menu 1 | Menu 2 | Menu 3 |
    +——–+——–+——–+
    | Sub Menu 1 |
    +————+
    | Sub Menu 2 |
    +————+
    | Sub Menu 2 – Item 1 |
    | Sub Menu 2 – Item 2 |
    | Sub Menu 2 – Item 3 |
    +————+
    | Sub Menu 3 |
    +————+
    | Sub Menu 4 |
    +————+

    The item 1, 2, 3 on sub menu 2 should only appear when mouse is hover link and if not, then dissapear. The code I’ve is:

    class site_nav_menu extends Walker_Nav_Menu {
      
    // add classes to ul sub-menus
    function start_lvl( &$output, $depth ) {
        // depth dependent classes
        $indent = ( $depth > 0  ? str_repeat( "\t", $depth ) : '' ); // code indent
        $display_depth = ( $depth + 1); // because it counts the first submenu as 0
        $classes = array('cdab-tm-submenu');
        $display_depth = ( $depth + 2);
    	$classes = array('cdab-tm-subsubmenu');
        $class_names = implode( ' ', $classes );
      
        // build html
        $output .= "\n" . $indent . '<ul class="' . $class_names . '">' . "\n";
    }
      
    // add main/sub classes to li's and links
     function start_el( &$output, $item, $depth, $args ) {
        global $wp_query;
        $indent = ( $depth > 0 ? str_repeat( "\t", $depth ) : '' ); // code indent
      
        // passed classes
        $classes = empty( $item->classes ) ? array() : (array) $item->classes;
        $class_names = esc_attr( implode( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item ) ) );
      
        // build html
        $output .= $indent . '<li>';
      
        // link attributes
        $attributes  = ! empty( $item->attr_title ) ? ' title="'  . esc_attr( $item->attr_title ) .'"' : '';
        $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 .= ' class="menu-link ' . ( $depth > 0 ? 'sub-menu-link' : 'main-menu-link' ) . '"';
      
        $item_output = sprintf( '%1$s<a%2$s>%3$s%4$s%5$s</a>%6$s',
            $args->before,
            $attributes,
            $args->link_before,
            apply_filters( 'the_title', $item->title, $item->ID ),
            $args->link_after,
            $args->after
        );
      
        // build html
        $output .= apply_filters( 'site_menu_start_el', $item_output, $item, $depth, $args );
    }
    }

    The problem is the menu didn’t work. If anyone can help me, I would appreciate it. Thanks in advance! 🙂

Viewing 8 replies - 1 through 8 (of 8 total)
  • Thread Starter Dot22

    (@dot22)

    I was searching, and the following link show the menu I want to adapt to WordPress. The problem is I can’t set the class tags on ul’s and li’s: http://codepen.io/WhiteWolfWizard/pen/MYQGQQ

    Someone can help me? Thanks! 🙂

    Moderator bcworkz

    (@bcworkz)

    The codepen example displays sub items on click. You want the same, but on hover, yes?

    In any case, does your theme display submenus on hover by default? I mean without your customization. If so, it seems to me like you are over complicating things. Doesn’t your theme’s default behavior pretty much work as desired when you add items as a third level?

    The default nav menu HTML structure is nested ul/li lists of menu items. That alone should be enough to manage menu behavior by CSS rules. You shouldn’t need a custom nav walker from what I can see. Special classes are not needed if you use the correct CSS selectors.

    Thread Starter Dot22

    (@dot22)

    Hello bcworkz! Yes, the example displays sub items on click but for my site it really doesn’t matter if the effect is on click or on hover. I’m using a custom theme (a child version of WordPress default theme) and I can’t configure the CSS rules of the menu to act like the previous example.

    Thanks for your reply and help!

    Thread Starter Dot22

    (@dot22)

    I tried to adapt it with WordPress default menu classes, but didn’t work. The codes I have:

    MENU:

    <div id="menubar-menu">
    <ul id="menu" class="menu"><li id="menu-item-100" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-home menu-item-100"><a href="#">Home</a></li>
    <li id="menu-item-103" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-has-children menu-item-103"><a href="#">Section 1</a>
    <ul class="sub-menu">
    	<li id="menu-item-127" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-127"><a href="#">Subsection 1</a></li>
    	<li id="menu-item-140" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-140"><a href="#">Subsection 2</a></li>
    <ul class="sub-menu">
    		<li id="menu-item-122" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-122"><a href="#">SUB subsection 1</a></li>
    		<li id="menu-item-121" class="menu-item menu-item-type-post_type menu-item-object-page menu-item-121"><a href="#">SUB subsection 2</a></li>
    </ul>
    	<li id="menu-item-141" class="menu-item menu-item-type-custom menu-item-object-custom menu-item-141"><a href="#">Subsection 3</a></li>
    </ul>
    </li>
    </ul></div>
    <script>
    $(document).ready(function () {
      $('#menu .menu-item.menu-item-has-children .trigger-sub-menu i').on('click', function () {
        $(this).toggleClass('fa-flip-vertical');
        $(this).parent().toggleClass('active');
        $('#menu .menu-item.menu-item-has-children .sub-menu').toggle();
        $('#menu .menu-item.menu-item-has-children .sub-menu .trigger-sub-menu i').removeClass('fa-flip-vertical').parent().removeClass('active');
        $('#menu .menu-item.menu-item-has-children .sub-menu').slideUp();
        return false;
      });
      $('#menu .menu-item.menu-item-has-children .sub-menu .sub-menu i').on('click', function () {
        $(this).toggleClass('fa-flip-vertical');
        $(this).parent().toggleClass('active');
        $('#menu .menu-item.menu-item-has-children .sub-menu').slideToggle(150);
        return false;
      });
    });
    </script>

    CSS:

    #menu .menu-item {
      float: left;
      margin: 10px 0 10px 5px;
    }
    #menu .menu-item a {
      position: relative;
      height: 30px;
      padding: 0 10px;
      border-radius: 2px;
      display: block;
      -webkit-transition: all 150ms ease;
      transition: all 150ms ease;
      color: #8aa4bb;
      line-height: 30px;
      white-space: nowrap;
    }
    #menu .menu-item a:hover, #menu .menu-item a:active {
      background: #8aa4bb;
      color: #fff;
    }
    #menu .menu-item a:active {
      background: #758b9f;
    }
    #menu .menu-item a[class*="trigger-"] {
      padding-right: 40px;
    }
    #menu .menu-item a i {
      position: absolute;
      top: 0;
      right: 0;
      bottom: 0;
      width: 30px;
      height: 30px;
      line-height: 30px;
      text-align: center;
    }
    #menu .menu-item a i:after {
      content: '';
      position: absolute;
      top: 0;
      left: 0;
      bottom: 0;
      height: 50%;
      margin: auto;
      border-left: 1px solid rgba(0, 0, 0, 0.15);
    }
    #menu .menu-item.menu-item-has-children {
      position: relative;
    }
    #menu .menu-item.menu-item-has-children .sub-menu {
      position: absolute;
      top: 0;
      right: 0;
      border-radius: 2px;
      background: #fff;
      display: none;
      overflow: hidden;
      box-shadow: 0 0 5px rgba(0, 0, 0, 0.3);
      -webkit-transform: translateY(35px);
              transform: translateY(35px);
    }
    #menu .menu-item.menu-item-has-children .sub-menu li {
      float: none;
      margin: 0;
    }
    #menu .menu-item.menu-item-has-children .sub-menu li a {
      border-radius: 0;
    }
    #menu .menu-item.menu-item-has-children .sub-menu .menu-item-has-children.sub-menu {
      border-top: 1px solid rgba(0, 0, 0, 0.15);
      background: #758b9f;
      display: none;
    }
    #menu .menu-item.menu-item-has-children .sub-menu .menu-item-has-children.sub-menu li {
      width: 100%;
      display: table;
    }
    #menu .menu-item.menu-item-has-children .sub-menu .menu-item-has-children.sub-menu li a {
      height: 25px;
      font-size: 8pt;
      color: #fff;
      line-height: 25px;
    }
    #menu .menu-item.menu-item-has-children .sub-menu .menu-item-has-children.sub-menu li:first-child a {
      margin-top: 5px;
    }
    #menu .menu-item.menu-item-has-children .sub-menu .menu-item-has-children.sub-menu li:last-child a {
      margin-bottom: 5px;
    }

    Any help will be appreciated!

    Moderator bcworkz

    (@bcworkz)

    It’s rare to successfully to mix and match elements from different menu systems. They tend to be complete, interdependent collections of code. I’m unclear on what was wrong with the default system. AFAIK it pretty much worked the way you want. Outside of cosmetic adjustments, it’s something I would recommend not messing with. Exactly which theme is your child based on?

    Thread Starter Dot22

    (@dot22)

    The theme is a child version of WordPress default theme: twentytwelve.

    My main problem is that I want to make the second/third level submenus show on the same column and not on the right/left side of the main column (like the example of Codepen: http://codepen.io/WhiteWolfWizard/pen/MYQGQQ). I’ve tried lot of codes and modifications and nothing works. 🙁

    Moderator bcworkz

    (@bcworkz)

    I see, thanks. Moving the menus into a single column should just take some CSS adjustment, but they would just cover the upper level content, not push it down. The best approaches would be to avoid altering the current system any more than necessary, or completely discarding all but the ul/li structure and starting over. In keeping with the minimal alteration approach, I would look at using the jQuery Accordion module to manage the display of elements. It should be readily adaptable. If any classes need to be added, it should be possible through one of the several filters in wp_nav_menu(). I don’t see any real need for a custom walker unless you are going to use the start over approach.

    Despite calling it a start over approach, avoid changing the walker any more than necessary. By start over, I’m thinking more along the lines of replacing all current classes and IDs with different ones so that there is no undue influence from the current CSS. The ul/li structure should be fine for most menuing systems. Your codepen example certainly uses it. You may also need some additional reset CSS to remove unwanted inheritance from the theme CSS. Your browser’s CSS inspector will help you determine this.

    Thread Starter Dot22

    (@dot22)

    Thanks for the reply bcworkz! I understand what you said and keep trying to modify only CSS classes to structure the menu but it didn’t works.

    I’m a bit confused on how to edit them. Anyone can help me with this codes? Thanks in advance! 🙂

Viewing 8 replies - 1 through 8 (of 8 total)
  • The topic ‘Creating custom menu’ is closed to new replies.