Sign in


Sign up


Navbar

by Dawid Adach,

Final result preview
Live preview

After all boring "administrative" work the time has come to some exciting stuff. Let's start real development.

We will begin from the top by creating navbar for our blog. Furthermore, we will connect it to WP in the way that we will be able to change the menu content without touching a single line of code.

Paste the following code inside header.php just below <body> tag.


<header>
    <!--Navbar-->
    <nav class="navbar navbar-expand-lg navbar-dark light-blue accent-4">
        <div class="container">
            <a class="navbar-brand" href="#">Navbar</a>
            <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
                aria-expanded="false" aria-label="Toggle navigation">
                <span class="navbar-toggler-icon"></span>
            </button>
            <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav mr-auto">
                    <li class="nav-item active">
                        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Features</a>
                    </li>
                    <li class="nav-item">
                        <a class="nav-link" href="#">Pricing</a>
                    </li>
                    <li class="nav-item btn-group">
                        <a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown 
                        </a>
                        <div class="dropdown-menu dropdown-primary" aria-labelledby="navbarDropdownMenuLink">
                            <a class="dropdown-item" href="#">Action</a>
                            <a class="dropdown-item" href="#">Another action</a>
                            <a class="dropdown-item" href="#">Something else here</a>
                        </div>
                    </li>
                </ul>
                <form class="form-inline">
                    <input class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search">
                </form>
            </div>
        </div>
    </nav>
    <!--/.Navbar-->
</header>
            

Navbar customization

Check our Navbar documentation for more layouts/skins.

This is standard MDB navbar. However, this is plain HTML, and that means that content inside (links, text) is hard coded. Every time we want to change anything (i.e. add new/modify existing link) we will have to edit our header.php file and upload it to a server. That's definitely not what we want. Let's make it more dynamic. Create a new folder and call it inc. Enter folder, create a new file with name mdb_bootstrap_navwalker.php and place the following code into it:


<?php
/**
 * Extended Walker class for use with the
 * Material Design for Bootstrap toolkit in Wordpress.
 * Based on https://gist.github.com/3765640
 * 
 */
class MDBBootstrapNavMenuWalker extends Walker_Nav_Menu {
  function start_lvl( &$output, $depth = 0, $args = array() ) {
    $indent = str_repeat( "\t", $depth );
    $submenu = ($depth > 0) ? ' sub-menu' : '';
    $output    .= "\n$indent<ul class=\"dropdown-menu$submenu depth_$depth\">\n";
  }
  function start_el( &$output, $item, $depth = 0, $args = array(), $id = 0 ) {
    $indent = ( $depth ) ? str_repeat( "\t", $depth ) : '';
    $li_attributes = '';
    $class_names = $value = '';
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    
    // managing divider: add divider class to an element to get a divider before it.
    $divider_class_position = array_search('divider', $classes);
    if($divider_class_position !== false){
      $output .= "<li class=\"divider\"></li>\n";
      unset($classes[$divider_class_position]);
    }
    
    $classes[] = ($args->has_children) ? 'dropdown' : '';
    $classes[] = ($item->current || $item->current_item_ancestor) ? 'active' : '';
    $classes[] = 'nav-item menu-item-' . $item->ID;
    if($depth && $args->has_children){
      $classes[] = 'dropdown-submenu';
    }
    $class_names = join( ' ', apply_filters( 'nav_menu_css_class', array_filter( $classes ), $item, $args ) );
    $class_names = ' class="' . esc_attr( $class_names ) . '"';
    $id = apply_filters( 'nav_menu_item_id', 'menu-item-'. $item->ID, $item, $args );
    $id = strlen( $id ) ? ' id="' . esc_attr( $id ) . '"' : '';
    $output .= $indent . '<li' . $id . $value . $class_names . $li_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 .= ($args->has_children)      ? ' class="dropdown-menu" aria-labelledby="dropdownMenu1"' : ' class="nav-link"';
    $item_output = $args->before;
    $item_output .= '<a'. $attributes .'>';
    $item_output .= $args->link_before . apply_filters( 'the_title', $item->title, $item->ID ) . $args->link_after;
    $item_output .= ($depth == 0 && $args->has_children) ? ' <b class="caret"></b></a>' : '</a>';
    $item_output .= $args->after;
    $output .= apply_filters( 'walker_nav_menu_start_el', $item_output, $item, $depth, $args );
  }
  
  function display_element( $element, &$children_elements, $max_depth, $depth=0, $args, &$output ) {
    //v($element);
    if ( !$element )
      return;
    $id_field = $this->db_fields['id'];
    //display this element
    if ( is_array( $args[0] ) )
      $args[0]['has_children'] = ! empty( $children_elements[$element->$id_field] );
    else if ( is_object( $args[0] ) )
      $args[0]->has_children = ! empty( $children_elements[$element->$id_field] );
    $cb_args = array_merge( array(&$output, $element, $depth), $args);
    call_user_func_array(array(&$this, 'start_el'), $cb_args);
    $id = $element->$id_field;
    // descend only when the depth is right and there are childrens for this element
    if ( ($max_depth == 0 || $max_depth > $depth+1 ) && isset( $children_elements[$id]) ) {
      foreach( $children_elements[ $id ] as $child ){
        if ( !isset($newlevel) ) {
          $newlevel = true;
          //start the child delimiter
          $cb_args = array_merge( array(&$output, $depth), $args);
          call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
        }
        $this->display_element( $child, $children_elements, $max_depth, $depth + 1, $args, $output );
      }
      unset( $children_elements[ $id ] );
    }
    if ( isset($newlevel) && $newlevel ){
      //end the child delimiter
      $cb_args = array_merge( array(&$output, $depth), $args);
      call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
    }
    //end this element
    $cb_args = array_merge( array(&$output, $element, $depth), $args);
    call_user_func_array(array(&$this, 'end_el'), $cb_args);
  }
}
?>    
            

Add the following code to the functions.php after the last function which we created (and before closing ?> tag).

        
/**
 * Include external files
 */
require_once('inc/mdb_bootstrap_navwalker.php');
             
/**
 * Setup Theme
 */
function MDB_setup() {
  // Navigation Menus
  register_nav_menus(array(
    'navbar' => __( 'Navbar Menu')
    ));
  // Add featured image support
    add_theme_support('post-thumbnails');
    add_image_size('main-full', 1078, 516, false); // main post image in full width
  }
  add_action('after_setup_theme', 'MDB_setup');
                                     
                                                                                     
              

Now let's get back to header.php and replace the following code:

        
<ul class="navbar-nav mr-auto">
    <li class="nav-item active">
        <a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="#">Features</a>
    </li>
    <li class="nav-item">
        <a class="nav-link" href="#">Pricing</a>
    </li>
    <li class="nav-item btn-group">
        <a class="nav-link dropdown-toggle" id="navbarDropdownMenuLink" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Dropdown 
        </a>
        <div class="dropdown-menu dropdown-primary" aria-labelledby="navbarDropdownMenuLink">
            <a class="dropdown-item" href="#">Action</a>
            <a class="dropdown-item" href="#">Another action</a>
            <a class="dropdown-item" href="#">Something else here</a>
        </div>
    </li>
</ul>
              

with this one:

        
<ul class="navbar-nav mr-auto">
  <?php
  if ( has_nav_menu( 'navbar' ) ) {
    wp_nav_menu( array(
    'menu'              => 'navbar',
    'theme_location'    => 'navbar',
    'depth'             => 2,
    'menu_class'        => 'navbar-nav mr-auto',
    'fallback_cb'       => 'wp_bootstrap_navwalker::fallback',
    'container'         => false,
    'walker'            => new MDBBootstrapNavMenuWalker())
    );
  } else
  echo "Please assign Navbar Menu in Wordpress Admin -> Appearance -> Menus -> Manage Locations";
  ?> 
</ul>

Refresh the page, you will notice that links which were there before have disappeared, instead, you can see now ugly text stating:

Please assign Navbar Menu in Wordpress Admin -> Appearance -> Menus -> Manage Locations

Let's do it. Open admin panel and navigate to Appearance -> Menus. Create a new menu, call it Navbar and add three items (posts/pages/custom links) to it. WordPress menu editing options Save menu and switch to Manage Locations tab. Assign our Navbar menu to Navbar Menu location.

WordPress Menu Locations manager

Now when you come back to your blog, you will notice that links which you have added, are visible in our navbar.

MDB Navbar

We've done quite a lot steps, let's analyze them now (don't be afraid that you do not understand what certain functions are doing. For now, you don't have to. We will learn that along tutorial. Information below is just a hint to give you brief idea on what we are doing):

New functions

mdb_bootstrap_navwalker.php - this is PHP function is responsible for building our output HTML of navbar depending on items which we choose from the admin menu. This code is using quite advanced PHP functions, we not gonna explain them now - we will back to them in next tutorials once we will get more familiar with PHP.

require_once('inc/mdb_bootstrap_navwalker.php'); - this PHP function includes given files and put it content in a place from where we call it. This allows us to split our functions.php file into multiple smaller files. That enhance our code readability. You don't have to split it and keep everything inside functions.php file instead, however, you will end up with a single file containing thousands line of code.

MDB_setup() - this is our function which we have created in order to register menu within WP and add featured image support to our theme.

register_nav_menus() - WP function which register place for our menu. As you noticed, in one of the last steps we assigned our menu to Menu location. This is how we created this location.

add_theme_support() - WP function which tells WP that our theme supports certain feature. In our case, we are adding feature image for posts. From now on when you edit a post you will see Feature image option, and you will be able to add a picture to each of the posts.

add_image_size() - WP function which defines size of our feature image. We will use it in next lessons.

wp_nav_menu() - WP function which informs WP that this is the place where we want to display. In this particular case, we are stating that we want to display Navbar menu inside our header.php file.

That's it! Our navbar is ready. Now we will take part of main part of our webpage.


If something doesn’t work as expected, you can download a final code for this lesson here:

Previous lesson Download Live preview Next lesson

Do you want to share?

Facebook Twitter Google +

About author


Dawid Adach

For more than 5 years Dawid was working as an IT Consultant specializing in SOA/EAI/ESB for banking domain. He was gaining experience working in countries like Netherlands, Belgium, Poland and India developing enterprise class systems for the biggest companies within domain.

Currently, Dawid’s main focus is design & web development. He designs and develop websites using Adobe Photoshop, HTML5 / CSS3, bootstrap, JS, Meteor, AJAX, PHP and SQL.

Comments 31

  • Dawid Adach

    Dear @zpzyyzp, This tutorial doesn't include dropdown feature. I will create tutorial about that soon.

  • zpzyyzp

    I have try the mdb_bootstrap_navwalker.php but it did not march the dropdown list in the bootstrap 4……

  • Dawid Adach

    Dear Liran, I will create a tutorial about that soon. Please follow us to get notification once it will be ready.

  • Liran Atli

    how can i include to my navbar collapse button or search form with wordpress functions?

  • Alan Mroczek

    Please remove the line `/*# sourceMappingURL=bootstrap.css.map */` from bootstrap.css

  • middll

    Hey Alan. Beings how the files are simply downloaded from this lesson and placed into the theme directory the origin for css/bootstrap.min.css.map must be coming from the files provided. It is also puzzling that the console in Safari displays the error (http://imgur.com/a/5xUPg) but Chrome does not (http://imgur.com/a/ylkXL).

  • Alan Mroczek

    Hi again Middll. This issue is very strange, because I haven't seen in your code including file that console displays as missing. This error means that file is included by some part of your code, but is not where it should or doesn't exist at all. It's hard to tell when it appears, you have to check every possible case. However file bootstrap.min.css.map shouldn't be included in your webpage code. You should search for that file in your code (probably next to some wp_enqueue_script function), and remove it.

  • middll

    Update: I went ahead and downloaded the final code for this lesson, moved the files into my theme directory after clearing it of any of my files, and loaded the webpage. The navbar is being displayed now; however, I'm still getting the following console error message: http://imgur.com/a/CcIap. I still do not know what was causing the issue with the code I copied and pasted, but alas. Does anyone know why this console error persists?

Leave a reply

Join MDB Affiliate Program

Get 30% profit from each sale

You earn 30% commission on affiliate sales, when a product is bought by a customer you referred, you will receive a 30% share.

Join us