Skip to main content
menu tabs and menu items

Adding custom menu tabs and menu items to navbar

Mobile Friendly Navigation Toolbar, shortly known as navbar, is a back-port of toolbar in Drupal 8. The problem it tries to solve is pretty obvious from it's name.

Navbar is an often used module in our Drupal projects. In our recent project we were asked to develop a bunch of menus to quickly access admin pages as and when needed. Unlike Shortcuts, we want this appear dynamically like notification.

For instance, if there are any new comments awaiting approval, the menu should show up and a few more items similar to this. Thought, Navbar could be leveraged for this requirements.

This mighty developer friendly module makes this possible for any module by implementing hook_navbar(). Similar to hook_menu(), an array of menu items to be returned but in renderable array format. If you need an example, function navbar_navbar() is a good place to get started.

The menu it offers can be seen as,

  1. The navbar tab by its name acting as menu item (e.g. Home)
  2. The navbar tab on click expands to show menu item(s) it has got underneath (e.g. Shortcuts) depends on the way navbar item defined in the hook_navbar().

Example code for #1,

<?php
/**
 * Implements hook_navbar().
 */
function mymodule_navbar() {
  $items = array();
  $count = db_query('SELECT COUNT(cid) FROM {comment} WHERE status = :status', array(
    ':status' => COMMENT_NOT_PUBLISHED,
  ))->fetchField();
  if ($count > 0) {
    $items['comment_unapproved'] = array(
      '#type' => 'navbar_item',
      'tab' => array(
        '#type' => 'link',
        '#title' => t('Unapproved comment (!count)', array('!count' => $count)),
        '#href' => 'admin/content/comment/approval',
        '#options' => array(
          'html' => TRUE,
          'attributes' => array(
            'title' => t('Approve comments'),
            'class' => array('navbar-icon', 'navbar-icon-comment-unapproved'),
          ),
        ),
      ),
      '#weight' => -20,
      '#wrapper_attributes' => array(
        'class' => array('pull-right'),
      ),
    );
  }
  return $items;
}
?>

 

Note: To keep this distinct from other menu tabs you can add custom CSS classes using '#wrapper_attributes'. I have 'pull-right' so I can place it on the right extreme of toolbar.

Example code for #2,

<?php
/**
 * Implements hook_navbar().
 */
function navbar_navbar() {
  global $user;
  $items = array();
  // Add logout & user account links or login link.
  if (module_exists('user')) {
    if ($user->uid) {
      $links = array(
        'account' => array(
          'title' => t('View profile'),
          'href' => 'user',
          'html' => TRUE,
          'attributes' => array(
            'title' => t('User account'),
          ),
        ),
        'logout' => array(
          'title' => t('Log out'),
          'href' => 'user/logout',
        ),
      );
    }
    else {
      $links = array(
        'login' => array(
          'title' => t('Log in'),
          'href' => 'user',
        ),
      );
    }
    $items['user'] = array(
      '#type' => 'navbar_item',
      'tab' => array(
        '#type' => 'link',
        '#title' => format_username($user),
        '#href' => 'user',
        '#options' => array(
          'attributes' => array(
            'title' => t('My account'),
            'class' => array('navbar-icon', 'navbar-icon-user',),
          ),
        ),
      ),
      'tray' => array(
        '#heading' => t('User account actions'),
        'user_links' => array(
          '#theme' => 'links__navbar_user',
          '#links' => $links,
          '#attributes' => array(
            'class' => array('menu', 'navbar-menu-user'),
          ),
        ),
      ),
      '#weight' => 100,
    );
  }
  return $items;
}
?>

 

Example 2, provides User name as menu tab. Once clicked, it shows the profile page link and logout link as menu items.

Unlike hook_menu(), these items are not cached so we can have dynamic menus.

I had to write custom css to get icon for my custom menu. Below is the CSS I used to place pencil icon besides the menu tab "unapproved comment".

.navbar-bar .navbar-icon-comment-unapproved:before {
  background-image: url("../../../contrib/navbar/icons/bebebe/pencil.svg");
}
.no-svg .navbar-bar .navbar-icon-comment-unapproved:before {
  background-image: url("../../../contrib/navbar/icons/bebebe/pencil.png");
}
.navbar-bar .navbar-icon-comment-unapproved:active:before,
.navbar-bar .navbar-icon-comment-unapproved.navbar-active:before {
  background-image: url("../../../contrib/navbar/icons/ffffff/pencil.svg");
}
.no-svg .navbar-bar .navbar-icon-comment-unapproved:active:before,
.no-svg .navbar-bar .navbar-icon-comment-unapproved.navbar-active:before {
  background-image: url("../../../contrib/navbar/icons/ffffff/pencil.png");
}

I hope this will help. Looking forward to share another interesting tip in next blog.

Comments

I'm interested in the 'pull-right' class, it appealed as an additional functionality set for the Navbar region module, adding a 'left' and 'right' region, however when I looked into it I noticed no mention of 'pull-right' in the Navbar source code nor did adding the class to a navbar item's #wrapper_attributes do anything, so I'm curious of what it is you're doing differently to make it happen?