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!


23 thoughts on “Add second menu to Twenty Twelve theme

  1. JR

    Hi! This tutorial works perfectly as you can see in http://www.buscarhotelesbaratos.es. In my site i use one of the menus to show information about the site (About, Contact, Press media kit…) and the other to show the categories of the site.
    Now i would like to modify the aspect of top menu to display text smaller, remove the lines, etc etc. I want that my visitors see that the main menu is the categories menu (the second) and leave the other leave less prominent in case they need information about the site or contact with me. Can you help me? Thanks a lot and sorry for my english!

    Reply
    1. Zeaks

      Post author

      The borders are defined by this

      
      .main-navigation ul.nav-menu, .main-navigation div.nav-menu > ul {
          border-bottom: 1px solid #EDEDED;
          border-top: 1px solid #EDEDED;
      }

      You should be able to add the id lower-navigation to it to remove them.

      #lower-navigation .main-navigation ul.nav-menu, #lower-navigation  .main-navigation div.nav-menu > ul {
          border-bottom: 0;
          border-top: 0;
      }

      Use the #lower-navigation conditional to apply styles to that particular menu.

      Reply
  2. mark

    …and if i want a menu1 with (about, services, portfolio, contact), and a secondary Portfolio menu that appear only after portfolio press? The menu1 remain on top of the site and the portfolio menu appear in another position…
    how can i do?
    thanks
    good, very good tutorial..

    Reply
  3. Pingback:

    如何给Twenty Twelve主题创建新菜单区域 | SayBlog.Me

  4. Chris Lenoski

    Hi, the menu works great except for the styling, using #lower-navigation .main-navigation to change the look but not working, any ideas?

    Reply

Leave a Reply

Please use the forums for questions that do not relate to this post.
Wrap all code in [code] Your Code Here [/code] tags.

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>