Get a custom primary navigation per page

In my last blog post I wrote about how to create a simple landing page template. In the text I’ve also mentioned, that you might want to create a custom navigation for the pages you create using this page template. In this blog post, I want to show you how to do that.

Create a menu for a landing page

First, we need to create a custom menu for the landing page. This can be done in either the customizer or the “Appearance -> Menues” section in the admin backend. For the name of the new menu, it’s easiest to use the same name as for the page slug. This will make sure that we can find the custom menu later.

Overwriting a menu by a custom menu

After we have created a new menu with the page slug, we have to dynamically use this new menu. Every menu item is saved in the database as a post type nav_menu_item. The menu itself is a nav_menu taxonomy term. When WordPress tries to load a menu for a menu location, it would query for this taxonomy. Here we can use a filter to get our custom menu with the following code:

function current_page_wp_get_nav_menu_object( $menu_obj, $menu ) {
	if ( $menu_obj instanceof WP_Term && 'primary' == $menu_obj->slug ) {
		$current_slug  = get_post_field( 'post_name', get_the_ID() );
		$page_menu_obj = get_term_by( 'slug', $current_slug, 'nav_menu' );

		if ( $page_menu_obj ) {
			$menu_obj = $page_menu_obj;
		}
	}

	return $menu_obj;
}
add_action( 'wp_get_nav_menu_object', 'current_page_wp_get_nav_menu_object', 11, 2 );

In line 2, we check for the menu location. If we forget to add this step, we would overwrite any menu on the page. So even footer menus, social menus, etc. In this case we will check for the location name primary, the main menu position of your theme may have a different name.

After this check, we get the current slug of the page, try to get the nav_menu term for this term and if we have found it, we will overwrite the original $menu_object to use our custom page menu.

Conclusion

Overwriting a template file is quite easy. Dynamically overwriting a menu being use on a specific position is not possible using template files, but becomes quits easy when using the right filter. Using this little code, you can now have a custom menu per landing page. If you just want to use the same custom menu, when using the page template from the blog post before, you can alternatively check in the filter, if the page template is used and then load another menu.

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

Leave a Reply

Your email address will not be published.