Add custom html to last sub-menu item

I’m adding a custom menu to my wordpress theme. I need to add custom html to the final submenu item – before the primary sub-menu closes </ul>

I have registered my new menu

//functions.php
function register_my_menus() {
register_nav_menus(
array(
  'accessories'  => __( 'Accessories Menu' )
)
);
}

and I have called my new menu in my header

//header.php
wp_nav_menu( array( 'theme_location' => 'accessories', 
                    'walker'   => BENZ_Walker_Nav_Menu_ACC                 
        ) ); 

I have attempted to modify a new Walker to add this div to my submenu, however this added the div for each menu item

// functions.php ==this adds one div foreach li==comment out
class BENZ_Walker_Nav_Menu_ACC extends Walker_Nav_Menu {

function start_lvl(&$output, $depth) {
    $output .= '<ul class="sub-menu">';
}
  function end_lvl(&$output, $depth) {
        //$output .='<div>the div that I want to show only once</div></ul>';
        $output .= '</ul>';
        }
    }       
}

Again the above example is commented out because it does not work for my needs

I have also tried to add append some html at the end of the menu with the following two eaxmples…

//functions.php == this shows custom html after the top-level `<li>`
function BENZ_menu_extras($menu, $args) {
if( 'accessories' !== $args->theme_location )
    return $menu;
return $menu . '<div>the div that I want to show only once</div>';
}
add_filter('wp_nav_menu_items','BENZ_menu_extras', 10, 2);

this is very close, however I do not need the html in the top level of hierarchy in the menu, but instead one level deeper.

I have also tried this example..

function add_last_nav_item($items, $args) {
if (!is_admin() && $args->theme_location == 'accessories') {
$items .= '<div>the div that I want to show only once</div>';
}
return $items;
}
add_filter( 'wp_nav_menu_items', 'add_last_nav_item', 10, 2 );

however this does the same as the first example listed…

How can we use either of the above functions with the $depth variable to add my div here….

<div class="accessories menu">
  <ul id="menu-accessories" class="menu sf-menu">
    <li id="menu-item-1905">
      <a class="sf-with-ul" href="http://#">ACCESSORIES</a>
      <ul class="sub-menu">
        <li id="menu-item-1897">
          <a class="sf-with-ul" href="http://#">stuff</a>
          <ul class="sub-menu">
            <li id="menu-item-1899">stuff1</li>
            <li id="menu-item-1898">stuff1</li>
          </ul>
        </li>
        <li id="menu-item-1903">
          <a class="sf-with-ul" href="http://#">other stuff</a>
          <ul class="sub-menu">
            <li id="menu-item-1906">other stuff1</li>
            <li id="menu-item-1907">other stuff2</li>
          </ul>
        </li>
        <li id="menu-item-1911">
          <a class="sf-with-ul" href="http://#">blue stuff</a>
          <ul class="sub-menu">
            <li id="menu-item-1912">blue stuff 1</li>
            <li id="menu-item-1913">blut stuff 2</li>
          </ul>
        </li>
    <!--This is where i want to put one div so its in the main submenu-->
    <div>the div that I want to show only once</div>
      </ul>
    </li>
  </ul>
</div>

https://jsfiddle.net/qpbpofpp/3/

Thanks for reading.

–BEGIN EDIT–
This is the closest I have gotten..

 //functions.php
 class BENZ_Walker_Nav_Menu_ACC extends Walker_Nav_Menu {
 function start_lvl(&$output, $depth) {
       $output .= '<ul class="sub-menu">';
}
function end_lvl(&$output, $depth) {
    if ($depth = 2){
        $output .= '<div>the div that I want to show only once</div></ul>';
    } else {
        $output .= '</ul>';
           }
    }    
}

except for now shows after all three of the sub menus, i just need it to show once

2 s
2

Ok, so it turns out that by default, $depth in the end_lvl() function starts at 0 when it’s a submenu and increments as the depth gets greater. So we need to test if {$depth} is equal to 0 to apply it only to the first set of submenus:

function end_lvl( &$output, $depth, $args ) {
    if( 0 == $depth ) {
        $output .= '<div>the div that I want to show only once</div>';
    }

    $indent = str_repeat( "\t", $depth );
    $output .= "{$indent}</ul>\n";
}

Leave a Comment