1

Is there a way to change the html of my wordpress page's navigation bar? (I'd like to add in several divs that will be controlled with media queries.)

Thanks for reading!

  • 1
    Have you tried a custom walker? – fuxia Dec 18 '14 at 3:04
  • @toscho No, I hadn't heard of that before reading the helpful responses below. That said, I've since decided to simply create my own header.php file in my custom child theme which lets me edit the html/css/php directly instead. – Rogare Dec 19 '14 at 14:32
3

Yes, you'll need to implement the walker class for this.

Here is a simple example.

$defaults = array(
    'theme_location' => 'primary',
    'container'      => 'ul',
    'menu_class'     => 'nav navbar-nav main-nav',
    'walker'         => new Primary_Walker_Nav_Menu()
);

wp_nav_menu( $defaults );

In the above block of code, the wp_nav_menu() function takes $defaults as argument. In the array $defaults, the last key is walker. Te walker key's value is object of a class Primary_Walker_Nav_Menu.

In functions.php file implement the following code:

class Primary_Walker_Nav_Menu extends Walker_Nav_Menu {
    function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0) {
        if (array_search('menu-item-has-children', $item->classes)) {
            $output .= sprintf("\n<li class='dropdown %s'><a href='%s' class=\"dropdown-toggle\" data-toggle=\"dropdown\" >%s</a>\n", ( array_search('current-menu-item', $item->classes) || array_search('current-page-parent', $item->classes) ) ? 'active' : '', $item->url, $item->title
            );
        } else {
            $output .= sprintf("\n<li %s><a href='%s'>%s</a>\n", ( array_search('current-menu-item', $item->classes) ) ? ' class="active"' : '', $item->url, $item->title
            );
        }
    }

    function start_lvl(&$output, $depth) {
        $indent = str_repeat("\t", $depth);
        $output .= "\n$indent<ul class=\"dropdown-menu\" role=\"menu\">\n";
    }
}

The start_el() method is used to add the opening HTML tag for a single tree item (such as <li>, <span>, or <a>) to $output.

The start_lvl() method is run when the walker reaches the start of a new "branch" in the tree structure.

Generally, this method is used to add the opening tag of a container HTML element (such as <ol>, <ul>, or <div>) to $output.


The output of the above implementation will result in the following HTML:

<ul id="menu-main-navigation" class="nav navbar-nav main-nav">
   <li class="dropdown ">
      <a href="http://karunshakya.com.np/services/" class="dropdown-toggle">Services</a>
      <ul class="dropdown-menu" role="menu">
         <li><a href="http://karunshakya.com.np/services/selection-et-recrutement/">Sélection et recrutement</a></li>
         <li><a href="http://karunshakya.com.np/services/mise-disposition-de-personnel/">Mise disposition de personnel</a></li>
         <li><a href="http://karunshakya.com.np/services/gestion-de-salaire/">Gestion de salaire</a></li>
      </ul>
   </li>
   <li><a href="http://karunshakya.com.np/news/">News</a></li>
   <li><a href="http://karunshakya.com.np/medias/">Medias</a></li>
   <li class="last-child"><a href="http://karunshakya.com.np/contactez-nous/">Contactez-nous</a></li>
</ul>

How to use the Walker Class:
http://code.tutsplus.com/tutorials/understanding-the-walker-class--wp-25401

  • Please edit your answer to include the relevant code and implementation in your answer. If that link ever goes bad then the answer doesn't help anyone. – Andrew Bartel Dec 18 '14 at 18:07
  • 1
    Edited. I hope my explanation helps in easily understanding the walker class. – Karun Dec 18 '14 at 19:46
2

If you're only looking to change the outer elements (not the li's themselves) you can pass into wp_nav_menu() the 'items_wrap' => '<ul id="%1$s" class="%2$s">%3$s</ul>' argument and edit it as needed, for example this shows how to wrap the list in a nav element and a div element:

'items_wrap' => '<div><nav><ul id="%1$s" class="%2$s">%3$s</ul></nav></div>',.

You could also pass in other elements to edit the content of the <li> and the <a> using 'before' => '', 'after' => '', 'link_before' => '', 'link_after' => ''.

If that doesn't help please show the required final HTML output you're trying to get.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.