Add second menu to Twenty Twelve theme

Here’s a step by step guide to adding a second menu area to a Twenty Twelve child theme. This menu will act the same as the default menu on mobile devices and display below the header area.

If you don’t know what a child theme is you can read more about it on the WordPress Codex or read my own article on how to Create a WordPress child theme

Prepare the child theme

  • Create a Twenty Twelve Child theme or you can download a blank one Here (make sure to edit the top of the style.css file to reflect your own name and theme name)
  • In the child theme folder, create a directory called “js” (without quotes)
  • Copy from the Twenty Twelve folder, header.php and inside the js folder copy navigation.js
  • Create a file called functions.php
  • Upload functions.php to your child theme folder
  • Upload header.php to your child theme folder
  • Upload navigation.js to your child theme folder inside the js folder

Your child theme now contains the proper files and directory structure for the next part. Follow these template modifications for the files in your child theme folder.

Template modifications

Open functions.php and add this. This code dequeues the original Twenty Twelve navigation.js file and queues our ownIt also registers our second menu area.

<?php

// de-queue navigation js
add_action('wp_print_scripts','tto_dequeue_navigation');
	function tto_dequeue_navigation() {
		wp_dequeue_script( 'twentytwelve-navigation' );
}
// load the new navigation js
	function tto_custom_scripts()
{

// Register the new navigation script
	wp_register_script( 'lowernav-script', get_stylesheet_directory_uri() . '/js/navigation.js', array(), '1.0', true );

// Enqueue the new navigation script 
	wp_enqueue_script( 'lowernav-script' );
}
add_action( 'wp_enqueue_scripts', 'tto_custom_scripts' );

// Add the new menu
register_nav_menus( array(
	'primary' => __( 'Top Menu (Above Header)', 'tto' ),
	'secondary' => __( 'Lower Menu (Below Header))', 'tto'),
) );

?>

Save and close functions.php

Add the menu to the header

Open header.php and around line 48 find this line

</header><!-- #masthead -->

Directly above that line add the following code. This adds a second menu call to the header.

<!-- Lower Navigation -->
<nav id="lower-navigation" class="main-navigation" role="navigation">
	<h3 class="menu-toggle"><?php _e( 'Lower Menu', 'twentytwelve' ); ?></h3>
	<div class="skip-link assistive-text"><a href="#content" title="<?php esc_attr_e( 'Skip to content', 'twentytwelve' ); ?>"><?php _e( 'Skip to content', 'twentytwelve' ); ?></a></div>
	<?php wp_nav_menu( array( 'theme_location' => 'secondary', 'menu_class' => 'nav-menu', 'fallback_cb' => false ) ); ?>
</nav><!-- #lower-navigation -->

You can change the name of the menu that appears on mobile by changing “Lower Menu” to whatever you prefer in this code.

We’re going to use the fallback_cb menu parameter so the new menu won’t list your pages in case you decide you don’t want to have it active. But remember, this will require you to create a new menu in Appearance > Menus and activate it before you’ll see the menu.

Save and close header.php

Add the javascript for mobile

Open /js/navigation.js, scroll to the very bottom and add the following code. We’re simply adding a copy of the current javascript but using a different ID #lower-navigation for the new menu. This will make the menu act the same as the default menu on mobile devices.

I’m not very good with javascript so there might be a better way to use a second ID for getElementById, if you know of one please let me know and I’ll update this.

// Lower Navigation
( function() {
	var button = document.getElementById( 'lower-navigation' ).getElementsByTagName( 'h3' )[0],
	    menu   = document.getElementById( 'lower-navigation' ).getElementsByTagName( 'ul' )[0];

	if ( undefined === button )
		return false;

	// Hide button if menu is missing or empty.
	if ( undefined === menu || ! menu.childNodes.length ) {
		button.style.display = 'none';
		return false;
	}

	button.onclick = function() {
		if ( -1 == menu.className.indexOf( 'nav-menu' ) )
			menu.className = 'nav-menu';

		if ( -1 != button.className.indexOf( 'toggled-on' ) ) {
			button.className = button.className.replace( ' toggled-on', '' );
			menu.className = menu.className.replace( ' toggled-on', '' );
		} else {
			button.className += ' toggled-on';
			menu.className += ' toggled-on';
		}
	};
} )();

Save and close navigation.js and activate your new child theme. Now visit Appearance > menus, create a new menu and add it to the new lower menu area.

If everything went well you should see a second menu in your Twenty Twelve child theme. Be sure to resize the browser and test the menu.

Bonus

Some of you might want to only display the lower menu, but you can’t because Twenty Twelve displays your pages if there isn’t a menu active. Here’s how to do it.

Open header.php and find around line 42

<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu' ) ); ?>

Change it to

<?php wp_nav_menu( array( 'theme_location' => 'primary', 'menu_class' => 'nav-menu', 'fallback_cb' => false ) ); ?>

Now visit Appearance > Menus and remove the menu from the top menu area and save. Adding the fallback_cb menu parameter prevents the menu from displaying your pages when there is no menu active.

If you want to remove the margin above the header and bring the header image closer to the top, you can add this to your CSS.

#site-navigation.main-navigation {
    margin-top: 0 ;
}

Enjoy your new menu and let me know how it worked out for you!

Comments

  1. premmarga says

    Hello, I tried, this but I don´t get it working. After changing funktion.php and upload nothing works anymore. Maybe you could give me a help.

    • says

      Hi Premmarga, there is already a menu area above the header. If youw ant to add another one on top of that, simply move the menu call

      <!-- Lower Navigation -->
      <nav id="lower-navigation" class="main-navigation" role="navigation">
          <h3 class="menu-toggle"><?php _e( 'Lower Menu', 'twentytwelve' ); ?></h3>
          <div class="skip-link assistive-text"><a href="#content" title="<?php esc_attr_e( 'Skip to content', 'twentytwelve' ); ? rel="nofollow">"><?php _e( 'Skip to content', 'twentytwelve' ); ?></a></div>
          <?php wp_nav_menu( array( 'theme_location' => 'secondary', 'menu_class' => 'nav-menu', 'fallback_cb' => false ) ); ?>
      </nav><!-- #lower-navigation -->

      To just abover the menu that’s already there. if you can;t figure this out, open a forum post and link your header code to pastebin.com

  2. says

    Hello Zeak, I have put a code of header.php in pastebin. and now I will put also my child css in there. but I not really know how pastbin works.

  3. ravi says

    HI Zeaks A big thanks to you, I am using wordpress from last 1.5 years and whatever i have learnt in wordpress is only because of your blog. thanks a lot buddy.

    I am using 2 menus in my website and i have copied your code to my child theme but the problem is only one menu is able to toggle when screen gets smaller. other menu does not toggle.

    • says

      Make sure you’ve followed the instructions for the javascript changes otherwise the menu will not open on mobile. If you’ve done that, paste all your code to pastebin.com and link it and I will take a look.

  4. David says

    Nice tutorial. Works great. My client wanted a second menu, but at the footer so this was perfect. I put the code at the top of footer.php and renamed the menu titles to “footer menu”. Works like a charm.

    • davidborrink says

      Well, not so fast. :-) My client tried it on her iPhone and the top menu button doesn’t show up, although it does show up when I’m logged in to the WP dashboard – even then, the toggle doesn’t work. The bottom menu button does work fine.

      Site is at http://connieclay.com

      Pastebin of Header, Footer, Javascript and Style sheet in this pastebin: http://pastebin.com/n8kzXZhQ

      • davidborrink says

        Zeke, I’ve got another situation like above. I placed the script and modified header file (both menus are in the header on this other site), and the main menu button is not responding in mobile, and the second added menu button is visible but the menu items are listed below it on this one. It doesn’t toggle, either. This site is in development so I’ve got no link to share for this one.

        So the site above in the previous note has the new added menu working fine. The second site has the menu “on” with no “off”.

        Any idea what’s going?

  5. davidborrink says

    On the second site, if it’s any help, I renamed the div for the added menu to “upper-navigation” instead of “site-navigation” because this menu needed different styling that the other.

    That means I took all the styles of “site-navigation”, made copies and renamed them “upper-navigation” so the menus could look different. Is it possible that I’m missing a key piece of CSS that has the menu in the “on” state since I created a new div in the menus? I’m not seeing it in the parent TwentyTwelve CSS at first glance. Maybe you can tip me off to something I’m overlooking.

  6. davidborrink says

    I removed the script from the first site and turned off my second menu. It would appear that it’s the script to add the mobile functions to the second menu is the problem. The first menu is working fine again with the default script. I’m no javascript expert, but I’m tossing out a guess that the latest version of TwentyTwelve is conflicting with your script?

Leave a Reply