Login with:


Or:


Not a member? Sign Up

Forgot Password?

Signup with:


Or:


Already have an account? Log in

MDB navbar displayed on iPhone

Navbar


Written 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-dark primary-color-dark">
        <!-- Collapse button-->
        <button class="navbar-toggler hidden-sm-up" type="button" data-toggle="collapse" data-target="#collapseEx">
            <i class="fa fa-bars"></i>
        </button>
        <div class="container">
            <!--Collapse content-->
            <div class="collapse navbar-toggleable-xs" id="collapseEx">
                <!--Navbar Brand-->
                <a class="navbar-brand" href="https://mdbootstrap.com/material-design-for-bootstrap/" target="_blank">MDB</a>
                <!--Links-->
                <ul class="nav navbar-nav">
                    <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">
                        <a class="nav-link" href="#">About</a>
                    </li>
                </ul>
            </div>
            <!--/.Collapse content-->
        </div>
    </nav>
    <!--/.Navbar-->
</header>
            

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="nav navbar-nav">
    <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">
        <a class="nav-link" href="#">About</a>
    </li>
</ul>
              

with this one:

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

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?


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 17

  • User avatar

    Willy

    Warning: Cannot modify header information - headers already sent by (output started at E:\OS\OpenServer\domains\wordpress.local\wp-content\themes\myfirstblog\inc\mdb_bootstrap_navwalker.php:88) in E:\OS\OpenServer\domains\wordpress.local\wp-includes\option.php on line 824

  • User avatar

    Willy

    http://prntscr.com/bm7cze

  • User avatar

    Willy

    I found the cause of the error. Sorry. The problem here is that you have gotten some text or whitespace (spaces, newline) before the opening PHP tag or after the closing PHP tag

  • Dawid Adach

    Willy, indeed whitespace are common issues in WordPress. The most common case is whitespace at the end of wp-config file in root folder. However, this may happen as well in case you have some whitespace in included files or functions.php itself at the beginning or end of file. I am happy to hear that you have solved your issue :)

  • olmostblue

    Hi, I followed all the instructions but when I refresh my page in the navbar I can't see the with submenu. I can't see errors in Chrome's console

  • Dawid Adach

    olmostblue, what exactly can't you see? Did you assign menu in WordPress administrator panel?

  • Subiyan Toro

    mdb-bootstrap-navwalker.php can work with dropdown menu?,. because i trying to create menu with submenu dosen't work, Thanks :)

  • Dawid Adach

    Dear Subiyan - currently it's not supported. That will be part of future tutorial lessons.

  • User avatar

    Shell

    Yes - it was whitespace in the wp-config that tricked me up too! :-)

  • Dawid Adach

    @Shell Yeah, that is tricky error... ;)

  • LCallaghan84

    Little suggestion: Make sure the Navbar brand is outside of the collapsible navbar. The site brand name should not be hidden in the navbar. :)

  • Dawid Adach

    Good point LCallaghan84 ! ;)

  • User avatar

    Tony

    Hi, I recently used this code without realizing it couldn't support sub-menus. Was that tutorial made yet? If not, is there another alternative I can use?

  • Dawid Adach

    @Tony, tutorial isn't ready , however submenus (Dropdowns) are available in MDW PRO (http://mdwp.io)

  • User avatar

    Tony

    Does the Pro version have the fix for the menus in tablet portrait mode? The menu stays open in that mode. (Using an iPad) Everywhere else it's fine.

  • User avatar

    Bartłomiej Malanowski

    @Tony, could you please contact me at b.malanowski@mdbootstrap.com and describe your problem with details?

  • User avatar

    Tony

    Thank you, Bart. I just sent the email.

Leave a reply

Card image cap

Create advanced websites and apps


With MDB Pro you can create easily and fast the most advanced projects.

2000+ stunning premium components, 50+ sections, 20+ templates, 30 plugins, direct contact with our team to help you with any questions and unlimited future updates.