Make WordPress Core

Opened 10 years ago

Last modified 7 years ago

#39040 reopened enhancement

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

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

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
10 years ago

  • Type feature requestenhancement

#2 @westonruter
10 years ago

  • Milestone Awaiting ReviewFuture Release
  • Summary Refresh Menu Locations in Customizer after refreshHide 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
10 years ago

  • Resolutionmaybelater
  • Status newclosed

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
10 years ago

  • Milestone Future Release

#5 @westonruter
10 years ago

  • MilestoneFuture Release
  • Resolution maybelater
  • Status closedreopened
  • Version4.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.