diff --git a/src/wp-admin/css/customize-controls.css b/src/wp-admin/css/customize-controls.css index df6e49feac..039477a37c 100644 --- a/src/wp-admin/css/customize-controls.css +++ b/src/wp-admin/css/customize-controls.css @@ -163,6 +163,15 @@ body { #customize-controls .customize-info .customize-panel-description.open + .no-widget-areas-rendered-notice { border-top: none; } +.no-widget-areas-rendered-notice { + font-style: italic; +} +.no-widget-areas-rendered-notice p:first-child { + margin-top: 0; +} +.no-widget-areas-rendered-notice p:last-child { + margin-bottom: 0; +} #customize-controls .customize-info .customize-section-description { margin-bottom: 15px; diff --git a/src/wp-admin/js/customize-widgets.js b/src/wp-admin/js/customize-widgets.js index 25c1eb5b7a..d3a4edcc64 100644 --- a/src/wp-admin/js/customize-widgets.js +++ b/src/wp-admin/js/customize-widgets.js @@ -13,7 +13,6 @@ // Link settings api.Widgets.data = _wpCustomizeWidgetsSettings || {}; l10n = api.Widgets.data.l10n; - delete api.Widgets.data.l10n; /** * wp.customize.Widgets.WidgetModel @@ -1577,36 +1576,84 @@ api.Panel.prototype.ready.call( panel ); panel.deferred.embedded.done(function() { - var panelMetaContainer, noRenderedAreasNotice, shouldShowNotice; + var panelMetaContainer, noticeContainer, updateNotice, getActiveSectionCount, shouldShowNotice; panelMetaContainer = panel.container.find( '.panel-meta' ); - noRenderedAreasNotice = $( '
', { + + // @todo This should use the Notifications API introduced to panels. See . + noticeContainer = $( '
', { 'class': 'no-widget-areas-rendered-notice' }); - noRenderedAreasNotice.append( $( '', { - text: l10n.noAreasRendered - } ) ); - panelMetaContainer.append( noRenderedAreasNotice ); + panelMetaContainer.append( noticeContainer ); - shouldShowNotice = function() { - return ( 0 === _.filter( panel.sections(), function( section ) { + /** + * Get the number of active sections in the panel. + * + * @return {number} Number of active sidebar sections. + */ + getActiveSectionCount = function() { + return _.filter( panel.sections(), function( section ) { return section.active(); - } ).length ); + } ).length; }; + /** + * Determine whether or not the notice should be displayed. + * + * @return {boolean} + */ + shouldShowNotice = function() { + var activeSectionCount = getActiveSectionCount(); + if ( 0 === activeSectionCount ) { + return true; + } else { + return activeSectionCount !== api.Widgets.data.registeredSidebars.length; + } + }; + + /** + * Update the notice. + * + * @returns {void} + */ + updateNotice = function() { + var activeSectionCount = getActiveSectionCount(), message, nonRenderedAreaCount, registeredAreaCount; + noticeContainer.empty(); + + registeredAreaCount = api.Widgets.data.registeredSidebars.length; + if ( activeSectionCount !== registeredAreaCount ) { + + if ( 0 !== activeSectionCount ) { + nonRenderedAreaCount = registeredAreaCount - activeSectionCount; + message = ( 1 === nonRenderedAreaCount ? l10n.someAreasShown.singular : l10n.someAreasShown.plural ).replace( '%d', nonRenderedAreaCount ); + } else { + message = ( 1 === registeredAreaCount ? l10n.noAreasShown.singular : l10n.noAreasShown.plural ).replace( '%d', registeredAreaCount ); + } + + noticeContainer.append( $( '

', { + text: message + } ) ); + noticeContainer.append( $( '

', { + text: l10n.navigatePreview + } ) ); + } + }; + updateNotice(); + /* * Set the initial visibility state for rendered notice. * Update the visibility of the notice whenever a reflow happens. */ - noRenderedAreasNotice.toggle( shouldShowNotice() ); + noticeContainer.toggle( shouldShowNotice() ); api.previewer.deferred.active.done( function () { - noRenderedAreasNotice.toggle( shouldShowNotice() ); + noticeContainer.toggle( shouldShowNotice() ); }); api.bind( 'pane-contents-reflowed', function() { var duration = ( 'resolved' === api.previewer.deferred.active.state() ) ? 'fast' : 0; + updateNotice(); if ( shouldShowNotice() ) { - noRenderedAreasNotice.slideDown( duration ); + noticeContainer.slideDown( duration ); } else { - noRenderedAreasNotice.slideUp( duration ); + noticeContainer.slideUp( duration ); } }); }); diff --git a/src/wp-includes/class-wp-customize-widgets.php b/src/wp-includes/class-wp-customize-widgets.php index 0cd2359d56..887c11fa0c 100644 --- a/src/wp-includes/class-wp-customize-widgets.php +++ b/src/wp-includes/class-wp-customize-widgets.php @@ -732,10 +732,27 @@ final class WP_Customize_Widgets { 'error' => __( 'An error has occurred. Please reload the page and try again.' ), 'widgetMovedUp' => __( 'Widget moved up' ), 'widgetMovedDown' => __( 'Widget moved down' ), - 'noAreasRendered' => __( 'There are no widget areas on the page shown, however other pages in this theme do have them.' ), + 'navigatePreview' => __( 'You can navigate to other pages on your site while using the Customizer to view and edit the widgets displayed on those pages.' ), + 'someAreasShown' => wp_array_slice_assoc( + /* translators: placeholder is the number of other widget areas registered */ + _n_noop( + 'Your theme has %d other widget area, but this particular page doesn\'t display it.', + 'Your theme has %d other widget areas, but this particular page doesn\'t display them.' + ), + array( 'singular', 'plural' ) + ), + 'noAreasShown' => wp_array_slice_assoc( + /* translators: placeholder is the total number of widget areas registered */ + _n_noop( + 'Your theme has %d widget area, but this particular page doesn\'t display it.', + 'Your theme has %d widget areas, but this particular page doesn\'t display them.' + ), + array( 'singular', 'plural' ) + ), 'reorderModeOn' => __( 'Reorder mode enabled' ), 'reorderModeOff' => __( 'Reorder mode closed' ), 'reorderLabelOn' => esc_attr__( 'Reorder widgets' ), + /* translators: placeholder is the count for the number of widgets found */ 'widgetsFound' => __( 'Number of widgets found: %d' ), 'noWidgetsFound' => __( 'No widgets found.' ), ), diff --git a/tests/qunit/fixtures/customize-widgets.js b/tests/qunit/fixtures/customize-widgets.js index 95ecce8fc6..14d43fb872 100644 --- a/tests/qunit/fixtures/customize-widgets.js +++ b/tests/qunit/fixtures/customize-widgets.js @@ -46,13 +46,27 @@ window._wpCustomizeWidgetsSettings = { } ], 'l10n': { - 'saveBtnLabel': 'Apply', - 'saveBtnTooltip': 'Save and preview changes before publishing them.', + 'error': 'An error has occurred. Please reload the page and try again.', + 'navigatePreview': 'You can navigate to other pages on your site while using the Customizer to view and edit the widgets displayed on those pages.', + 'noAreasShown': { + 'plural': 'Your theme has %d widget areas, but this particular page doesn\'t display them.', + 'singular': 'Your theme has %d widget area, but this particular page doesn\'t display it.' + }, + 'noWidgetsFound': 'No widgets found.', 'removeBtnLabel': 'Remove', 'removeBtnTooltip': 'Trash widget by moving it to the inactive widgets sidebar.', - 'error': 'An error has occurred. Please reload the page and try again.', + 'reorderLabelOn': 'Reorder widgets', + 'reorderModeOff': 'Reorder mode closed', + 'reorderModeOn': 'Reorder mode enabled', + 'saveBtnLabel': 'Apply', + 'saveBtnTooltip': 'Save and preview changes before publishing them.', + 'someAreasShown': { + 'plural': 'Your theme has %d other widget areas, but this particular page doesn\'t display them.', + 'singular': 'Your theme has %d other widget area, but this particular page doesn\'t display it.' + }, + 'widgetMovedDown': 'Widget moved down', 'widgetMovedUp': 'Widget moved up', - 'widgetMovedDown': 'Widget moved down' + 'widgetsFound': 'Number of widgets found: %d' }, 'tpl': { 'widgetReorderNav': '
Move to another area…Move downMove up
',