WordPress.org

Make WordPress Core

Opened 3 years ago

Last modified 7 months ago

#39040 reopened enhancement

Hide references to nav menu locations that are not visible in the customizer preview

Reported by: khela Owned by:
Milestone: Future Release Priority: normal
Severity: normal Version: 4.3
Component: Customize Keywords:
Focuses: Cc:
PR Number:

Description

Could be helpful to have menu locations automatically updated when switching template parts. For example if I have two header style:

header-singlemenu.php

<?php wp_nav_menu( array(
    'theme_location' => 'primary',
));

header-doublemenu.php

<?php
wp_nav_menu( array(
    'theme_location' => 'primary-left',
));
wp_nav_menu( array(
    'theme_location' => 'primary-right',
));

Those got by

  <?php get_template_part('header', get_theme_mod('header_style','singlemenu') ); ?>

where header_style obviously can be singlemenu or doublemenu
in functions.php i have

<?php
    if(get_theme_mod('header_style', 'singlemenu') == 'singlemenu')
    {
        register_nav_menu( 'primary', __( 'Primary Menu', 'theme-slug' ) );
    }
    else
    {
        register_nav_menu( 'primary-left', __( 'Left Menu', 'theme-slug' ) );
        register_nav_menu( 'primary-right', __( 'Right Menu', 'theme-slug' ) );
    }

When switching header style in customizer, menu location are not updated. You are bound to save your customization, reload the page and then you can be able to see new location.

https://i.gyazo.com/9fe4cca23b88c55877d65431c756f3a4.gif

Change History (5)

#1 @khela
3 years ago

  • Type changed from feature request to enhancement

#2 @westonruter
3 years ago

  • Milestone changed from Awaiting Review to Future Release
  • Summary changed from Refresh Menu Locations in Customizer after refresh to Hide references to nav menu locations that are not visible in the customizer preview

@khela thanks for the report. You raise an interesting use case. The best way to accomplish this right now would be to make use of the active_callback. This will get you most of the way:

<?php
add_action( 'customize_register', function( WP_Customize_Manager $wp_customize ) {
        $primary_menu_location_control = $wp_customize->get_control( 'nav_menu_locations[primary]' );
        $primary_left_menu_location_control = $wp_customize->get_control( 'nav_menu_locations[primary-left]' );
        $primary_right_menu_location_control = $wp_customize->get_control( 'nav_menu_locations[primary-right]' );

        $single_menus_active_callback = function() {
                return get_theme_mod( 'header_style', 'singlemenu' ) === 'singlemenu';
        };
        $plural_menus_active_callback = function() {
                return get_theme_mod( 'header_style', 'singlemenu' ) !== 'singlemenu';
        };
        $primary_menu_location_control->active_callback = $single_menus_active_callback;
        $primary_left_menu_location_control->active_callback = $plural_menus_active_callback;
        $primary_right_menu_location_control->active_callback = $plural_menus_active_callback;
}, 20 );

What this won't do is ensure that the nav menu location checkboxes are hidden when editing a nav menu in the customizer. This would need to be some additional JS that disables/hides those nav menu locations. Ideally this should all happen by default when a nav menu location is not available in the preview just like sections for widget sidebars not shown in the preview when they are not rendered.

This is also related to lazy-loading settings on demand: #28580.

#3 @khela
3 years ago

  • Resolution set to maybelater
  • Status changed from new to closed

Thank you @westonruter for your answer. My test is exactly as you wrote with active callbacks, it work in the static part of customizer but if you want nav locations checkboxes toggled when switching a setting you need to have this:

$.each({
  'header_style': {
    controls: [
      'nav_menu_locations[primary]',
      'nav_menu_locations[primary-left]',
      'nav_menu_locations[primary-right]'
    ],
    aux: ['singlemenu', 'doublemenu', 'doublemenu'],
    callback: function(to, aux) {
      return aux === to;
    }
  }
}, function(settingId, o) {
  api(settingId, function(setting) {
    $.each(o.controls, function(i, controlId) {
      api.control(controlId, function(control) {
        var visibility = function(to) {
          if ('aux' in o) {
            control.container.toggle(o.callback(to, o.aux[i]));
          } else {
            control.container.toggle(o.callback(to));
          }
        };
        visibility(setting.get());
        setting.bind(visibility);
      });
    });
  });
});

So, this work but the problem is that could be useless to register nav menu locations for maybe using only one of these.
Finally, I think that nav_menu_location control should be organized/updated to support dynamic menu locations.

#4 @netweb
3 years ago

  • Milestone Future Release deleted

#5 @westonruter
3 years ago

  • Milestone set to Future Release
  • Resolution maybelater deleted
  • Status changed from closed to reopened
  • Version set to 4.3

I'd consider the active_callback a partial solution, not a complete one. I think there is more work to do here.

Note: See TracTickets for help on using tickets.