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!

64 thoughts on “Add second menu to Twenty Twelve theme

  1. premmarga

    Hello Zeaks, now I´ve got it working, I only don´t get it what I have to change to get the second menu on the top, above the header like in http://babybirds.de/. You already gave Paul an answer on this, but I don´t know where to move the position of the menu, and I would like to call it topmenu, written already in the function.php, but where to change this the other files.
    I hope you can help me. her is my website http://www.ahoi-kultur.de

    1. Zeaks

      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

    1. Martin

      Below is my function.php for my 2012 child theme. I need the posts page to have a full page width or with one sidebar. I have managed to do that with the rest of the pages by creating a page template without the extra sidebar. I have tried applying the front-page template or the full-width template to the blog page but all in vain. It still gives me the three column like the homepage.

      current_post%2 == 0 ) $classes[] = ‘two-column-post-left';
      endif;
      return $classes;
      }

      ?>

      <?php
      function new_excerpt_more( $more ) {
      return ' ‘ . __(‘Read More’, ‘your-text-domain’) . ‘‘;
      }
      add_filter( ‘excerpt_more’, ‘new_excerpt_more’ );
      ?>

      __( ‘Extra Sidebar’, ‘tto’ ),
      ‘id’ => ‘sidebar-4′,
      ‘description’ => __( ‘The Left Sidebar. Displayed on all but full width and homepage template.’, ‘mytheme’ ),
      ‘before_widget’ => ”,
      ‘after_widget’ => “”,
      ‘before_title’ => ”,
      ‘after_title’ => ”,
      ) );
      }
      add_action( ‘widgets_init’, ‘mytheme_widgets_init’ );
      ?>

  2. ravi

    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.

  3. David

    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.

  4. davidborrink

    Zeak, I figured out a MAJOR reason why this suddenly wasn’t working and you need to know about it. It has to do with the updated Twenty Twelve theme (version 1.5) released with WordPress 4.0.

    There is a key line in the menus that changed. See this forum post: https://wordpress.org/support/topic/mobile-menu-doesnt-work?replies=24 for the details. The h3 class has become a button class.

    You will need to change the code in your javascript from “.getElementsByTagName( ‘h3′ )” to “.getElementsByClassName( ‘menu-toggle’ )”

    That completely solved my problem.

    (AND PLEASE feel free to delete all my comments above except the first one on August 30! People don’t need to read all my struggles with my goofed up attempts to not follow your instructions

  5. Pingback: ein zweites Menü für Twenty Twelve | Oh nein!

  6. Wakki

    Hello Zeaks

    I am very glad I found your tutorial and it worked fine. Thank you very much.
    I have a question though.
    On small screen, like it should, your method creates 2 toggle buttons for 2 menus.
    I would like to have just 1 toggle button that opens the 2 menus listed under each other. Do you know a way to create that?
    I was experimenting but didn’t succeed.
    Thanks in advance.

  7. davidborrink

    Ho boy. Double goofs.

    1. I just discovered tonight that I used your javascript example by itself and never tacked it on to a copy of the full javascript file from the parent theme. [facepalm] No wonder it didn’t work.

    2. I didn’t have the mobile menu’s CSS files from the parent theme in the child theme. Since I restyled the new menu differently than the main menu—and both have their own class—I needed to have an additional copy of the mobile CSS files with the class alterred. That made the menus closed as they needed to be. And gave them full function.

Leave a Comment

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

*
*