[resolved] Removing nav_menu from custom page templates (13 posts)

  1. Misamee
    Posted 5 years ago #


    I've created a new custom page template for a child theme (parent theme is Hybrid).

    This custom page template will be used for landing page and will need a less cluttered layout.

    In my functions.php, I've already removed all widgets (I'll see later if and which widget to put back), but I also need to remove all menus from this page: no navigations, no widget (yet), but just some layout and specific contents.

    For the widgets, I've simply set the $sidebars_widgets to an empty array, but I don't know what to do it with nav_menu objects/locations.

    My last attempt is to hook a function to the 'init' action:

    function landing_page_template_nav_menus() {
    	if (is_page_template('page-landingpage.php')) {
    		$locations = get_nav_menu_locations();
    		foreach ($locations as $location)
    	return $sidebars_widgets;

    Of course, this doesn't work, most likely because the 'init' action doesn't know yet the current page template.
    I could try with other hooks (actually I did with some of them, without results), but I'd like to use the right one.

    Of course I could also play with CSS, but I prefer to have unused/unwanted html totally removed from the page source.

    To clarify:
    I want to write the code as if I'm unaware of all nav_menu locations (to make the code more reusable in other themes). That's why I'm trying to use a loop.

    Bottom line, I need to find when to call this function, i.e. the right hook.

  2. Mark / t31os

    Posted 5 years ago #

    You could try template_redirect that should be early enough to make the changes you need, but late enough for conditional tags like is_page_template() to return correctly.

  3. Misamee
    Posted 5 years ago #

    Thank you Mark.

    The fact is that I'm not even sure my if code (see the code above, in my first post) is correct.

    However, I've just tried, but the menus still appears: If my code is right, then the template_redirect hook doesn't help.

  4. Mark / t31os

    Posted 5 years ago #

    You need to use the location, which in the array is the key not the value, update your loop to..

    foreach ($locations as $location => $n ) {

    And see if that helps..

  5. Misamee
    Posted 5 years ago #

    Thank you again Mark.

    Unfortunately this is still not working.

    Just to verify that my function is called, I've added echo '**********'; right after $locations = get_nav_menu_locations(); and indeed, the function is called only once and the echo prints the start right at the beginning of the html (before the `<!DOCTYPE html>').

    So, the code can see the right page template, I do unregister all nav_menu (with the code you've provided), but still nothing happens.

    I've also tried to move the echo '**********'; inside the foreach() and I get the stars printed three times, so, is indeed doing something.

    I suppose something else is putting them back.

  6. Mark / t31os

    Posted 5 years ago #

    Is this function attached to the action i suggested?

    If so, it seems strange you have a return statement at the end referencing sidebar widgets.

    Would you mind clarifying what your function does(aside from the discussed aspects), and where it hooks.

  7. Misamee
    Posted 5 years ago #

    Yes, sorry: it has a return statement because in all my attempts, I've also tried using this function as a hook for a filter.
    The return as been removed in the current version of the code.
    And yes, right now is hooked to the template_redirect.

    To recap, I'm using Hybrid Theme. This is the current code (only the interested portions):

    [Code moderated as per the Forum Rules. Please use the pastebin]

    As you can see, I use the if ( !is_admin() ) function to check when to hook to some filters. However, I've tried also putting add_action('template_redirect', 'landing_page_template_nav_menus'); outside the if ( !is_admin() ), with no changes in the resulting html.

  8. Mark / t31os

    Posted 5 years ago #

    Ok a little bit of misunderstanding on our part, all unregister_nav_menu does is unregister the location, which is easily evidenced by viewing the menu administration area, it does not remove menus already registered to that location though..

    I don't have any ideas how to work around that just yet, but thought you might be interested to know the reasoning the code doesn't act as expected.

  9. Mark / t31os

    Posted 5 years ago #

    Did a little backtracing and looked at the functions that are called when menus are output, ultimately the problem is a result of the data stored elsewhere, but after a little fiddling around i worked out a way to filter that data to make sure the menu disappears.

    $locations = get_nav_menu_locations();
    add_action( 'template_redirect', 'test_menu_removal' );
    add_filter( 'theme_mod_nav_menu_locations', 'remove_from_theme_mods' );
    function test_menu_removal() {
    	if( is_page_template( 'page-landingpage.php' ) ) {
    		global $locations;
    		foreach( $locations as $location => $n ) {
    	remove_filter( 'theme_mod_nav_menu_locations', 'remove_from_theme_mods' );
    function remove_from_theme_mods( $r ) {
    	global $locations;
    	foreach( $locations as $location => $n ) {
    		if( isset( $r[$location] ) )
    			unset( $r[$location] );
    	return $r;

    Just remember, wp_nav_menu uses a fallback function when it can't find a menu to display, and if memory serves that's wp_page_menu, so whilst the above will essentially remove the menu, it does result in another menu being generated(the fallback - wp_page_menu).

    Hope that helps in any case... :)

    For reference, here's the 3 files that contain the various functions i've been digging through(to save you needing to backtrace yourself), incase you want to get stuck in and see if you can find alternative / better ways to tackle what you need.


  10. Misamee
    Posted 5 years ago #


    This actually solved the problem. Now I'll go through the code and reference links, to better understand what is doing it, but yes, it definitely works!

    Thank you very much Mark!

    P.S.: about the misunderstanding, I'm not too surprised: sometimes I forget that I'm not a native speaker and that I must be more clear when I write my issues ;)

  11. Mark / t31os

    Posted 5 years ago #

    Happy to have helped... :)

    Best of luck with your site and coding.

  12. Chrisdigital
    Posted 4 years ago #

    Following up on this, I have a similar problem...

    I'm developing a Hybrid prototype child theme strip out the 'secondary' menu location I don't want on the interior pages.

    I can't seem to get this to work for the functions.php file...


    I know this is native to the base code as of 3.1 but I'n not sure what I'm doing wrong.

    I would rather avoid just hiding the menu with css or pulling out sidebars in the code but call it conditionally for the homepage and strip it out for the other templates to better future proof my child theme and leave the sidebar in for other purposes.

  13. Chrisdigital
    Posted 4 years ago #

    Nevermind, after some sleep and caffeine I realized Prototype was circumventing normal tactics to register/call the menus so I edited menu-secondary.php in my child theme to be conditional for only my homepage and that worked...

    if ( has_nav_menu( 'secondary' ) && (is_front_page()) ) : ?>

Topic Closed

This topic has been closed to new replies.

About this Topic