WordPress.org

Make WordPress Core

Changeset 41768


Ignore:
Timestamp:
10/05/2017 02:21:22 AM (8 months ago)
Author:
westonruter
Message:

Customize: Improve the menu creation flow.

Often, folks run into two issues when they create new menus: they click "Add a Menu" thinking it will add a new page to their menu, or they forget to assign their new menu to a location, and then wonder why it doesn't show up on their site.

This commit rearranges the order of items in the menu panel, and updates the flow for creating a menu by breaking it up into steps. Additionally, more help text has been added to guide people through the process of creating a menu.

Also adds default type lookups for Panel and Section instances. See #30741.

Props bpayton, obenland, westonruter, celloexpessions, afercia, melchoyce, zoonini, michelleweber.
Fixes #40104.

Location:
trunk
Files:
1 added
13 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-admin/css/customize-controls.css

    r41750 r41768  
    558558}
    559559
    560 #customize-theme-controls .control-panel-content .control-section:nth-child(2),
    561 #customize-theme-controls .control-panel-nav_menus .control-section:nth-child(3) {
     560#customize-theme-controls .control-panel-content:not(.control-panel-nav_menus) .control-section:nth-child(2),
     561#customize-theme-controls .control-panel-nav_menus .control-section-nav_menu,
     562#customize-theme-controls .control-section-nav_menu_locations .accordion-section-title {
    562563    border-top: 1px solid #ddd;
     564}
     565
     566#customize-theme-controls .control-panel-nav_menus .control-section-nav_menu + .control-section-nav_menu {
     567    border-top: none;
    563568}
    564569
     
    662667}
    663668
    664 .customize-section-description-container {
     669.customize-section-description-container,
     670.control-section-nav_menu .customize-section-description-container {
    665671    margin-bottom: 15px;
    666672}
  • trunk/src/wp-admin/css/customize-nav-menus.css

    r41711 r41768  
    11#customize-theme-controls #accordion-section-menu_locations {
    22    position: relative;
    3     margin-bottom: 15px;
     3    margin-top: 15px;
    44}
    55
    66#customize-theme-controls #accordion-section-menu_locations > .accordion-section-title {
    77    border-bottom-color: #ddd;
     8    margin-top: 15px;
     9}
     10
     11#customize-theme-controls .customize-section-title-nav_menus-heading,
     12#customize-theme-controls .customize-section-title-menu_locations-heading,
     13#customize-theme-controls .customize-section-title-menu_locations-description {
     14    padding: 0 12px 0 12px;
     15}
     16
     17#customize-theme-controls .customize-control-description.customize-section-title-menu_locations-description {
     18    /* Override the default italic style for control descriptions */
     19    font-style: normal;
    820}
    921
     
    2638    vertical-align: middle;
    2739    line-height: 28px;
     40}
     41
     42#customize-controls .customize-control-nav_menu_name {
     43    margin-bottom: 12px;
     44}
     45
     46.customize-control-nav_menu_name p:last-of-type {
     47    margin-bottom: 0;
     48}
     49
     50#customize-new-menu-submit {
     51    float: right;
     52    min-width: 85px;
     53}
     54
     55#customize-new-menu-submit-description {
     56    margin: 0;
    2857}
    2958
     
    176205}
    177206
    178 .menu-settings .customize-control-checkbox label {
     207.wp-customizer .menu-location-settings {
     208    margin-top: 12px;
     209    border-top: none;
     210}
     211
     212.wp-customizer .control-section-nav_menu .menu-location-settings {
     213    margin-top: 24px;
     214    border-top: 1px solid #ddd;
     215    padding-top: 12px;
     216}
     217
     218.menu-settings .customize-control-checkbox label,
     219.menu-location-settings .customize-control-checkbox label {
    179220    line-height: 1;
    180221}
    181222
    182223/* @todo update selector or potentially remove */
    183 .menu-settings .customize-control.customize-control-checkbox {
     224.menu-settings .customize-control.customize-control-checkbox,
     225.menu-location-settings .customize-control.customize-control-checkbox {
    184226    margin-bottom: 8px; /* Override collapsing at smaller viewports. */
    185227}
     
    739781#accordion-section-add_menu {
    740782    margin: 15px 12px;
    741     overflow: hidden;
    742 }
    743 
    744 .new-menu-section-content {
    745     display: none;
    746     padding: 15px 0 0 0;
    747     clear: both;
    748 }
    749 
    750 /* @todo update selector */
    751 #accordion-section-add_menu .accordion-section-title {
    752     padding-left: 45px;
    753 }
    754 
    755 /* @todo update selector */
    756 #accordion-section-add_menu .accordion-section-title:before {
    757     font: normal 20px/1 dashicons;
    758     position: absolute;
    759     top: 12px;
    760     left: 14px;
    761     content: "\f132";
     783    text-align: right;
     784}
     785
     786#accordion-section-add_menu h3,
     787#accordion-section-add_menu .customize-add-menu-button {
     788    margin: 0;
     789}
     790
     791#accordion-section-add_menu .customize-add-menu-button {
     792    font-weight: normal;
    762793}
    763794
     
    773804}
    774805
     806.assigned-menu-locations-title p {
     807    margin: 0 0 8px 0;
     808}
     809
    775810li.assigned-to-menu-location .menu-delete-item {
    776811    display: none;
     
    809844}
    810845
    811 .customize-control-nav_menu {
     846.customize-control-nav_menu .new-menu-item-invitation {
     847    margin-top: 0;
     848    margin-bottom: 0;
     849}
     850
     851.customize-control-nav_menu .customize-control-nav_menu-buttons {
    812852    margin-top: 12px;
    813853}
  • trunk/src/wp-admin/js/customize-controls.js

    r41750 r41768  
    12351235         */
    12361236        initialize: function ( id, options ) {
    1237             var section = this;
    1238             Container.prototype.initialize.call( section, id, options );
     1237            var section = this, params;
     1238            params = options.params || options;
     1239
     1240            // Look up the type if one was not supplied.
     1241            if ( ! params.type ) {
     1242                _.find( api.sectionConstructor, function( Constructor, type ) {
     1243                    if ( Constructor === section.constructor ) {
     1244                        params.type = type;
     1245                        return true;
     1246                    }
     1247                    return false;
     1248                } );
     1249            }
     1250
     1251            Container.prototype.initialize.call( section, id, params );
    12391252
    12401253            section.id = id;
     
    25082521         */
    25092522        initialize: function ( id, options ) {
    2510             var panel = this;
    2511             Container.prototype.initialize.call( panel, id, options );
     2523            var panel = this, params;
     2524            params = options.params || options;
     2525
     2526            // Look up the type if one was not supplied.
     2527            if ( ! params.type ) {
     2528                _.find( api.panelConstructor, function( Constructor, type ) {
     2529                    if ( Constructor === panel.constructor ) {
     2530                        params.type = type;
     2531                        return true;
     2532                    }
     2533                    return false;
     2534                } );
     2535            }
     2536
     2537            Container.prototype.initialize.call( panel, id, params );
     2538
    25122539            panel.embed();
    25132540            panel.deferred.embedded.done( function () {
     
    30963123     * @param {string} options.section          - The ID of the section the control belongs to.
    30973124     * @param {mixed}  [options.setting]        - The ID of the main setting or an instance of this setting.
    3098      * @param {mixed}  options.settings         - An object with keys (e.g. default) that maps to setting IDs or Setting/Value objects, or an array of setting IDs or Setting/Value objects.   
     3125     * @param {mixed}  options.settings         - An object with keys (e.g. default) that maps to setting IDs or Setting/Value objects, or an array of setting IDs or Setting/Value objects.
    30993126     * @param {mixed}  options.settings.default - The ID of the setting the control relates to.
    31003127     * @param {string} options.settings.data    - @todo Is this used?
     
    31083135
    31093136        defaults: {
     3137            label: '',
     3138            description: '',
    31103139            active: true,
    31113140            priority: 10
  • trunk/src/wp-admin/js/customize-nav-menus.js

    r41726 r41768  
    812812                panel.saveManageColumnsState();
    813813            });
     814
     815            // Wait until after construction to patch the UI
     816            _.defer( function () {
     817
     818                panel.contentContainer.find( '#accordion-section-menu_locations' ).prepend(
     819                    wp.template( 'nav-menu-locations-header' )( api.Menus.data )
     820                );
     821
     822                panel.contentContainer.find( '#accordion-section-add_menu .accordion-section-title' ).replaceWith(
     823                    wp.template( 'nav-menu-create-menu-section-title' )
     824                );
     825            } );
    814826        },
    815827
     
    962974
    963975        populateControls: function() {
    964             var section = this, menuNameControlId, menuAutoAddControlId, menuControl, menuNameControl, menuAutoAddControl;
     976            var section = this,
     977                menuNameControlId,
     978                menuLocationsControlId,
     979                menuAutoAddControlId,
     980                menuDeleteControlId,
     981                menuControl,
     982                menuNameControl,
     983                menuLocationsControl,
     984                menuAutoAddControl,
     985                menuDeleteControl;
    965986
    966987            // Add the control for managing the menu name.
     
    9971018            }
    9981019
     1020            // Add the menu locations control.
     1021            menuLocationsControlId = section.id + '[locations]';
     1022            menuLocationsControl = api.control( menuLocationsControlId );
     1023            if ( ! menuLocationsControl ) {
     1024                menuLocationsControl = new api.controlConstructor.nav_menu_locations( menuLocationsControlId, {
     1025                    section: section.id,
     1026                    priority: 999,
     1027                    settings: {
     1028                        'default': section.id
     1029                    },
     1030                    menu_id: section.params.menu_id
     1031                } );
     1032                api.control.add( menuLocationsControl.id, menuLocationsControl );
     1033                menuControl.active.set( true );
     1034            }
     1035
    9991036            // Add the control for managing the menu auto_add.
    10001037            menuAutoAddControlId = section.id + '[auto_add]';
     
    10051042                    label: '',
    10061043                    section: section.id,
    1007                     priority: 999,
     1044                    priority: 1000,
    10081045                    settings: {
    10091046                        'default': section.id
     
    10141051            }
    10151052
     1053            // Add the control for deleting the menu
     1054            menuDeleteControlId = section.id + '[delete]';
     1055            menuDeleteControl = api.control( menuDeleteControlId );
     1056            if ( ! menuDeleteControl ) {
     1057                menuDeleteControl = new api.Control( menuDeleteControlId, {
     1058                    section: section.id,
     1059                    priority: 1001,
     1060                    templateId: 'nav-menu-delete-button'
     1061                } );
     1062                api.control.add( menuDeleteControl.id, menuDeleteControl );
     1063                menuDeleteControl.active.set( true );
     1064                menuDeleteControl.deferred.embedded.done( function () {
     1065                    menuDeleteControl.container.find( 'button' ).on( 'click', function() {
     1066                        var menuId = section.params.menu_id;
     1067                        var menuControl = api.Menus.getMenuControl( menuId );
     1068                        menuControl.setting.set( false );
     1069                    });
     1070                } );
     1071            }
    10161072        },
    10171073
     
    10941150     *
    10951151     * Customizer section for new menus.
    1096      * Note that 'new_menu' must match the WP_Customize_New_Menu_Section::$type.
    10971152     *
    10981153     * @constructor
     
    11071162         */
    11081163        attachEvents: function() {
    1109             var section = this;
    1110             this.container.on( 'click', '.add-menu-toggle', function() {
    1111                 if ( section.expanded() ) {
    1112                     section.collapse();
    1113                 } else {
    1114                     section.expand();
    1115                 }
    1116             });
    1117         },
    1118 
    1119         /**
    1120          * Update UI to reflect expanded state.
    1121          *
    1122          * @since 4.1.0
    1123          *
    1124          * @param {Boolean} expanded
    1125          */
    1126         onChangeExpanded: function( expanded ) {
    11271164            var section = this,
    1128                 button = section.container.find( '.add-menu-toggle' ),
    1129                 content = section.contentContainer,
    1130                 customizer = section.headContainer.closest( '.wp-full-overlay-sidebar-content' );
    1131             if ( expanded ) {
    1132                 button.addClass( 'open' );
    1133                 button.attr( 'aria-expanded', 'true' );
    1134                 content.slideDown( 'fast', function() {
    1135                     customizer.scrollTop( customizer.height() );
    1136                 });
    1137             } else {
    1138                 button.removeClass( 'open' );
    1139                 button.attr( 'aria-expanded', 'false' );
    1140                 content.slideUp( 'fast' );
    1141                 content.find( '.menu-name-field' ).removeClass( 'invalid' );
    1142             }
    1143         },
    1144 
    1145         /**
    1146          * Find the content element.
    1147          *
    1148          * @since 4.7.0
    1149          *
    1150          * @returns {jQuery} Content UL element.
    1151          */
    1152         getContent: function() {
    1153             return this.container.find( 'ul:first' );
     1165                container = section.container,
     1166                contentContainer = section.contentContainer;
     1167
     1168            /*
     1169             * We have to manually handle section expanded because we do not
     1170             * apply the `accordion-section-title` class to this button-driven section.
     1171             */
     1172            container.on( 'click', '.customize-add-menu-button', function() {
     1173                section.expand();
     1174            });
     1175
     1176            contentContainer.on( 'keydown', '.menu-name-field', function( event ) {
     1177                if ( 13 === event.which ) { // Enter.
     1178                    section.submit();
     1179                }
     1180            } );
     1181            contentContainer.on( 'click', '#customize-new-menu-submit', function( event ) {
     1182                section.submit();
     1183                event.stopPropagation();
     1184                event.preventDefault();
     1185            } );
     1186
     1187            api.Section.prototype.attachEvents.apply( this, arguments );
     1188        },
     1189
     1190        /**
     1191         * Set up the control.
     1192         *
     1193         * @since 4.9.0
     1194         */
     1195        ready: function() {
     1196            this.populateControls();
     1197        },
     1198
     1199        /**
     1200         * Create the controls for this section.
     1201         *
     1202         * @since 4.9.0
     1203         */
     1204        populateControls: function() {
     1205            var section = this,
     1206                menuNameControlId,
     1207                menuLocationsControlId,
     1208                newMenuSubmitControlId,
     1209                menuNameControl,
     1210                menuLocationsControl,
     1211                newMenuSubmitControl;
     1212
     1213            menuNameControlId = section.id + '[name]';
     1214            menuNameControl = api.control( menuNameControlId );
     1215            if ( ! menuNameControl ) {
     1216                menuNameControl = new api.controlConstructor.nav_menu_name( menuNameControlId, {
     1217                    label: api.Menus.data.l10n.menuNameLabel,
     1218                    description: api.Menus.data.l10n.newMenuNameDescription,
     1219                    section: section.id,
     1220                    priority: 0
     1221                } );
     1222                api.control.add( menuNameControl.id, menuNameControl );
     1223                menuNameControl.active.set( true );
     1224            }
     1225
     1226            menuLocationsControlId = section.id + '[locations]';
     1227            menuLocationsControl = api.control( menuLocationsControlId );
     1228            if ( ! menuLocationsControl ) {
     1229                menuLocationsControl = new api.controlConstructor.nav_menu_locations( menuLocationsControlId, {
     1230                    section: section.id,
     1231                    priority: 1,
     1232                    menu_id: ''
     1233                } );
     1234                api.control.add( menuLocationsControlId, menuLocationsControl );
     1235                menuLocationsControl.active.set( true );
     1236            }
     1237
     1238            newMenuSubmitControlId = section.id + '[submit]';
     1239            newMenuSubmitControl = api.control( newMenuSubmitControlId );
     1240            if ( !newMenuSubmitControl ) {
     1241                newMenuSubmitControl = new api.Control( newMenuSubmitControlId, {
     1242                    section: section.id,
     1243                    priority: 1,
     1244                    templateId: 'nav-menu-submit-new-button'
     1245                } );
     1246                api.control.add( newMenuSubmitControlId, newMenuSubmitControl );
     1247                newMenuSubmitControl.active.set( true );
     1248            }
     1249        },
     1250
     1251        /**
     1252         * Create the new menu with name and location supplied by the user.
     1253         *
     1254         * @since 4.9.0
     1255         */
     1256        submit: function() {
     1257            var section = this,
     1258                contentContainer = section.contentContainer,
     1259                nameInput = contentContainer.find( '.menu-name-field' ).first(),
     1260                name = nameInput.val(),
     1261                menuSection,
     1262                customizeId,
     1263                placeholderId = api.Menus.generatePlaceholderAutoIncrementId();
     1264
     1265            if ( ! name ) {
     1266                nameInput.addClass( 'invalid' );
     1267                nameInput.focus();
     1268                return;
     1269            }
     1270
     1271            customizeId = 'nav_menu[' + String( placeholderId ) + ']';
     1272
     1273            // Register the menu control setting.
     1274            api.create( customizeId, customizeId, {}, {
     1275                type: 'nav_menu',
     1276                transport: api.Menus.data.settingTransport,
     1277                previewer: api.previewer
     1278            } );
     1279            api( customizeId ).set( $.extend(
     1280                {},
     1281                api.Menus.data.defaultSettingValues.nav_menu,
     1282                {
     1283                    name: name
     1284                }
     1285            ) );
     1286
     1287            /*
     1288             * Add the menu section (and its controls).
     1289             * Note that this will automatically create the required controls
     1290             * inside via the Section's ready method.
     1291             */
     1292            menuSection = new api.Menus.MenuSection( customizeId, {
     1293                panel: 'nav_menus',
     1294                title: displayNavMenuName( name ),
     1295                customizeAction: api.Menus.data.l10n.customizingMenus,
     1296                priority: 10,
     1297                menu_id: placeholderId
     1298            } );
     1299            api.section.add( customizeId, menuSection );
     1300
     1301            // Clear name field.
     1302            nameInput.val( '' );
     1303            nameInput.removeClass( 'invalid' );
     1304
     1305            contentContainer.find( '.assigned-menu-location input[type=checkbox]' ).each( function() {
     1306                var checkbox = $( this ),
     1307                navMenuLocationSetting;
     1308
     1309                if ( checkbox.prop( 'checked' ) ) {
     1310                    navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' );
     1311                    navMenuLocationSetting.set( placeholderId );
     1312
     1313                    // Reset state for next new menu
     1314                    checkbox.prop( 'checked', false );
     1315                }
     1316            } );
     1317
     1318            wp.a11y.speak( api.Menus.data.l10n.menuAdded );
     1319
     1320            // Focus on the new menu section.
     1321            api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow...
    11541322        }
    11551323    });
     
    15131681                    $adjacentFocusTarget.focus(); // keyboard accessibility
    15141682                } );
     1683
     1684                control.setting.set( false );
    15151685            } );
    15161686        },
     
    20352205
    20362206        ready: function() {
     2207            var control = this;
     2208
     2209            if ( control.setting ) {
     2210                var settingValue = control.setting();
     2211
     2212                control.nameElement = new api.Element( control.container.find( '.menu-name-field' ) );
     2213
     2214                control.nameElement.bind(function( value ) {
     2215                    var settingValue = control.setting();
     2216                    if ( settingValue && settingValue.name !== value ) {
     2217                        settingValue = _.clone( settingValue );
     2218                        settingValue.name = value;
     2219                        control.setting.set( settingValue );
     2220                    }
     2221                });
     2222                if ( settingValue ) {
     2223                    control.nameElement.set( settingValue.name );
     2224                }
     2225
     2226                control.setting.bind(function( object ) {
     2227                    if ( object ) {
     2228                        control.nameElement.set( object.name );
     2229                    }
     2230                });
     2231            }
     2232        }
     2233    });
     2234
     2235    /**
     2236     * wp.customize.Menus.MenuLocationsControl
     2237     *
     2238     * Customizer control for a nav menu's locations.
     2239     *
     2240     * @since 4.9.0
     2241     * @constructor
     2242     * @augments wp.customize.Control
     2243     */
     2244    api.Menus.MenuLocationsControl = api.Control.extend({
     2245
     2246        /**
     2247         * Set up the control.
     2248         *
     2249         * @since 4.9.0
     2250         */
     2251        ready: function () {
     2252            var control = this;
     2253
     2254            control.container.find( '.assigned-menu-location' ).each(function() {
     2255                var container = $( this ),
     2256                    checkbox = container.find( 'input[type=checkbox]' ),
     2257                    element = new api.Element( checkbox ),
     2258                    navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' ),
     2259                    isNewMenu = control.params.menu_id === '',
     2260                    updateCheckbox = isNewMenu ? _.noop : function( checked ) {
     2261                        element.set( checked );
     2262                    },
     2263                    updateSetting = isNewMenu ? _.noop : function( checked ) {
     2264                        navMenuLocationSetting.set( checked ? control.params.menu_id : 0 );
     2265                    },
     2266                    updateSelectedMenuLabel = function( selectedMenuId ) {
     2267                        var menuSetting = api( 'nav_menu[' + String( selectedMenuId ) + ']' );
     2268                        if ( ! selectedMenuId || ! menuSetting || ! menuSetting() ) {
     2269                            container.find( '.theme-location-set' ).hide();
     2270                        } else {
     2271                            container.find( '.theme-location-set' ).show().find( 'span' ).text( displayNavMenuName( menuSetting().name ) );
     2272                        }
     2273                    };
     2274
     2275                updateCheckbox( navMenuLocationSetting.get() === control.params.menu_id );
     2276
     2277                checkbox.on( 'change', function() {
     2278                    // Note: We can't use element.bind( function( checked ){ ... } ) here because it will trigger a change as well.
     2279                    updateSetting( this.checked );
     2280                } );
     2281
     2282                navMenuLocationSetting.bind( function( selectedMenuId ) {
     2283                    updateCheckbox( selectedMenuId === control.params.menu_id );
     2284                    updateSelectedMenuLabel( selectedMenuId );
     2285                } );
     2286                updateSelectedMenuLabel( navMenuLocationSetting.get() );
     2287            });
     2288        }
     2289    });
     2290
     2291    /**
     2292     * wp.customize.Menus.MenuAutoAddControl
     2293     *
     2294     * Customizer control for a nav menu's auto add.
     2295     *
     2296     * @constructor
     2297     * @augments wp.customize.Control
     2298     */
     2299    api.Menus.MenuAutoAddControl = api.Control.extend({
     2300
     2301        ready: function() {
    20372302            var control = this,
    20382303                settingValue = control.setting();
     
    20532318            };
    20542319
    2055             control.nameElement = new api.Element( control.container.find( '.menu-name-field' ) );
    2056 
    2057             control.nameElement.bind(function( value ) {
    2058                 var settingValue = control.setting();
    2059                 if ( settingValue && settingValue.name !== value ) {
    2060                     settingValue = _.clone( settingValue );
    2061                     settingValue.name = value;
    2062                     control.setting.set( settingValue );
    2063                 }
    2064             });
    2065             if ( settingValue ) {
    2066                 control.nameElement.set( settingValue.name );
    2067             }
    2068 
    2069             control.setting.bind(function( object ) {
    2070                 if ( object ) {
    2071                     control.nameElement.set( object.name );
    2072                 }
    2073             });
    2074         }
    2075 
    2076     });
    2077 
    2078     /**
    2079      * wp.customize.Menus.MenuAutoAddControl
    2080      *
    2081      * Customizer control for a nav menu's auto add.
    2082      *
    2083      * @constructor
    2084      * @augments wp.customize.Control
    2085      */
    2086     api.Menus.MenuAutoAddControl = api.Control.extend({
    2087 
    2088         ready: function() {
    2089             var control = this,
    2090                 settingValue = control.setting();
    2091 
    2092             /*
    2093              * Since the control is not registered in PHP, we need to prevent the
    2094              * preview's sending of the activeControls to result in this control
    2095              * being deactivated.
    2096              */
    2097             control.active.validate = function() {
    2098                 var value, section = api.section( control.section() );
    2099                 if ( section ) {
    2100                     value = section.active();
    2101                 } else {
    2102                     value = false;
    2103                 }
    2104                 return value;
    2105             };
    2106 
    21072320            control.autoAddElement = new api.Element( control.container.find( 'input[type=checkbox].auto_add' ) );
    21082321
     
    21812394
    21822395            this._setupAddition();
    2183             this._setupLocations();
    21842396            this._setupTitle();
    21852397
     
    22112423                }
    22122424            }
     2425
     2426            /*
     2427             * Wait for menu items to be added.
     2428             * Ideally, we'd bind to an event indicating construction is complete,
     2429             * but deferring appears to be the best option today.
     2430             */
     2431            _.defer( function () {
     2432                control.updateInvitationVisibility();
     2433            } );
    22132434        },
    22142435
     
    22362457                }
    22372458            } );
    2238 
    2239             control.container.find( '.menu-delete-item .button-link-delete' ).on( 'click', function( event ) {
    2240                 event.preventDefault();
    2241                 control.setting.set( false );
    2242             });
    22432459        },
    22442460
     
    23922608            widgetTemplate.find( '.nav-menu-widget-no-menus-message:first' ).toggle( 0 === navMenuCount );
    23932609            widgetTemplate.find( 'option[value=' + String( menuId ) + ']' ).remove();
    2394         },
    2395 
    2396         // Setup theme location checkboxes.
    2397         _setupLocations: function() {
    2398             var control = this;
    2399 
    2400             control.container.find( '.assigned-menu-location' ).each(function() {
    2401                 var container = $( this ),
    2402                     checkbox = container.find( 'input[type=checkbox]' ),
    2403                     element,
    2404                     updateSelectedMenuLabel,
    2405                     navMenuLocationSetting = api( 'nav_menu_locations[' + checkbox.data( 'location-id' ) + ']' );
    2406 
    2407                 updateSelectedMenuLabel = function( selectedMenuId ) {
    2408                     var menuSetting = api( 'nav_menu[' + String( selectedMenuId ) + ']' );
    2409                     if ( ! selectedMenuId || ! menuSetting || ! menuSetting() ) {
    2410                         container.find( '.theme-location-set' ).hide();
    2411                     } else {
    2412                         container.find( '.theme-location-set' ).show().find( 'span' ).text( displayNavMenuName( menuSetting().name ) );
    2413                     }
    2414                 };
    2415 
    2416                 element = new api.Element( checkbox );
    2417                 element.set( navMenuLocationSetting.get() === control.params.menu_id );
    2418 
    2419                 checkbox.on( 'change', function() {
    2420                     // Note: We can't use element.bind( function( checked ){ ... } ) here because it will trigger a change as well.
    2421                     navMenuLocationSetting.set( this.checked ? control.params.menu_id : 0 );
    2422                 } );
    2423 
    2424                 navMenuLocationSetting.bind(function( selectedMenuId ) {
    2425                     element.set( selectedMenuId === control.params.menu_id );
    2426                     updateSelectedMenuLabel( selectedMenuId );
    2427                 });
    2428                 updateSelectedMenuLabel( navMenuLocationSetting.get() );
    2429 
    2430             });
    24312610        },
    24322611
     
    26082787            } );
    26092788
     2789            menuControl.updateInvitationVisibility( menuItemControls );
    26102790            menuControl.container.find( '.reorder-toggle' ).toggle( menuItemControls.length > 1 );
    26112791        },
     
    26822862
    26832863            return menuItemControl;
     2864        },
     2865
     2866        /**
     2867         * Show an invitation to add new menu items when there are no menu items.
     2868         *
     2869         * @since 4.9.0
     2870         *
     2871         * @param {wp.customize.controlConstructor.nav_menu_item[]} optionalMenuItemControls
     2872         */
     2873        updateInvitationVisibility: function ( optionalMenuItemControls ) {
     2874            var menuItemControls = optionalMenuItemControls || this.getMenuItemControls();
     2875
     2876            this.container.find( '.new-menu-item-invitation' ).toggle( menuItemControls.length === 0 );
    26842877        }
    26852878    } );
    2686 
    2687     /**
    2688      * wp.customize.Menus.NewMenuControl
    2689      *
    2690      * Customizer control for creating new menus and handling deletion of existing menus.
    2691      * Note that 'new_menu' must match the WP_Customize_New_Menu_Control::$type.
    2692      *
    2693      * @constructor
    2694      * @augments wp.customize.Control
    2695      */
    2696     api.Menus.NewMenuControl = api.Control.extend({
    2697         /**
    2698          * Set up the control.
    2699          */
    2700         ready: function() {
    2701             this._bindHandlers();
    2702         },
    2703 
    2704         _bindHandlers: function() {
    2705             var self = this,
    2706                 name = $( '#customize-control-new_menu_name input' ),
    2707                 submit = $( '#create-new-menu-submit' );
    2708             name.on( 'keydown', function( event ) {
    2709                 if ( 13 === event.which ) { // Enter.
    2710                     self.submit();
    2711                 }
    2712             } );
    2713             submit.on( 'click', function( event ) {
    2714                 self.submit();
    2715                 event.stopPropagation();
    2716                 event.preventDefault();
    2717             } );
    2718         },
    2719 
    2720         /**
    2721          * Create the new menu with the name supplied.
    2722          */
    2723         submit: function() {
    2724 
    2725             var control = this,
    2726                 container = control.container.closest( '.accordion-section-new-menu' ),
    2727                 nameInput = container.find( '.menu-name-field' ).first(),
    2728                 name = nameInput.val(),
    2729                 menuSection,
    2730                 customizeId,
    2731                 placeholderId = api.Menus.generatePlaceholderAutoIncrementId();
    2732 
    2733             if ( ! name ) {
    2734                 nameInput.addClass( 'invalid' );
    2735                 nameInput.focus();
    2736                 return;
    2737             }
    2738 
    2739             customizeId = 'nav_menu[' + String( placeholderId ) + ']';
    2740 
    2741             // Register the menu control setting.
    2742             api.create( customizeId, customizeId, {}, {
    2743                 type: 'nav_menu',
    2744                 transport: api.Menus.data.settingTransport,
    2745                 previewer: api.previewer
    2746             } );
    2747             api( customizeId ).set( $.extend(
    2748                 {},
    2749                 api.Menus.data.defaultSettingValues.nav_menu,
    2750                 {
    2751                     name: name
    2752                 }
    2753             ) );
    2754 
    2755             /*
    2756              * Add the menu section (and its controls).
    2757              * Note that this will automatically create the required controls
    2758              * inside via the Section's ready method.
    2759              */
    2760             menuSection = new api.Menus.MenuSection( customizeId, {
    2761                 panel: 'nav_menus',
    2762                 title: displayNavMenuName( name ),
    2763                 customizeAction: api.Menus.data.l10n.customizingMenus,
    2764                 type: 'nav_menu',
    2765                 priority: 10,
    2766                 menu_id: placeholderId
    2767             } );
    2768             api.section.add( menuSection );
    2769 
    2770             // Clear name field.
    2771             nameInput.val( '' );
    2772             nameInput.removeClass( 'invalid' );
    2773 
    2774             wp.a11y.speak( api.Menus.data.l10n.menuAdded );
    2775 
    2776             // Focus on the new menu section.
    2777             api.section( customizeId ).focus(); // @todo should we focus on the new menu's control and open the add-items panel? Thinking user flow...
    2778         }
    2779     });
    27802879
    27812880    /**
     
    27882887        nav_menu: api.Menus.MenuControl,
    27892888        nav_menu_name: api.Menus.MenuNameControl,
    2790         nav_menu_auto_add: api.Menus.MenuAutoAddControl,
    2791         new_menu: api.Menus.NewMenuControl
     2889        nav_menu_locations: api.Menus.MenuLocationsControl,
     2890        nav_menu_auto_add: api.Menus.MenuAutoAddControl
    27922891    });
    27932892
  • trunk/src/wp-includes/class-wp-customize-control.php

    r41750 r41768  
    771771
    772772/**
     773 * WP_Customize_Nav_Menu_Locations_Control class.
     774 */
     775require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' );
     776
     777/**
    773778 * WP_Customize_Nav_Menu_Auto_Add_Control class.
    774779 */
     
    776781
    777782/**
    778  * WP_Customize_New_Menu_Control class.
    779  */
    780 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' );
    781 
    782 /**
    783783 * WP_Customize_Date_Time_Control class.
    784784 */
  • trunk/src/wp-includes/class-wp-customize-manager.php

    r41750 r41768  
    316316        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-location-control.php' );
    317317        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-name-control.php' );
     318        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-locations-control.php' );
    318319        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-auto-add-control.php' );
    319         require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-control.php' );
    320320
    321321        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menus-panel.php' );
     
    325325        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-sidebar-section.php' );
    326326        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' );
    327         require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' );
    328327
    329328        require_once( ABSPATH . WPINC . '/customize/class-wp-customize-custom-css-setting.php' );
  • trunk/src/wp-includes/class-wp-customize-nav-menus.php

    r41670 r41768  
    396396        $temp_nav_menu_item_setting = new WP_Customize_Nav_Menu_Item_Setting( $this->manager, 'nav_menu_item[-1]' );
    397397
     398        $num_locations = count( get_registered_nav_menus() );
     399        if ( 1 === $num_locations ) {
     400            $locations_description = __( 'Your theme can display menus in one location.' );
     401        } else {
     402            /* translators: %s: number of menu locations */
     403            $locations_description = sprintf( _n( 'Your theme can display menus in %s location.', 'Your theme can display menus in %s locations.', $num_locations ), number_format_i18n( $num_locations ) );
     404        }
     405
    398406        // Pass data to JS.
    399407        $settings = array(
     
    401409            'itemTypes'            => $this->available_item_types(),
    402410            'l10n'                 => array(
    403                 'untitled'          => _x( '(no label)', 'missing menu item navigation label' ),
    404                 'unnamed'           => _x( '(unnamed)', 'Missing menu name.' ),
    405                 'custom_label'      => __( 'Custom Link' ),
    406                 'page_label'        => get_post_type_object( 'page' )->labels->singular_name,
    407                 /* translators: %s: menu location */
    408                 'menuLocation'      => _x( '(Currently set to: %s)', 'menu' ),
    409                 'menuNameLabel'     => __( 'Menu Name' ),
    410                 'itemAdded'         => __( 'Menu item added' ),
    411                 'itemDeleted'       => __( 'Menu item deleted' ),
    412                 'menuAdded'         => __( 'Menu created' ),
    413                 'menuDeleted'       => __( 'Menu deleted' ),
    414                 'movedUp'           => __( 'Menu item moved up' ),
    415                 'movedDown'         => __( 'Menu item moved down' ),
    416                 'movedLeft'         => __( 'Menu item moved out of submenu' ),
    417                 'movedRight'        => __( 'Menu item is now a sub-item' ),
     411                'untitled'               => _x( '(no label)', 'missing menu item navigation label' ),
     412                'unnamed'                => _x( '(unnamed)', 'Missing menu name.' ),
     413                'custom_label'           => __( 'Custom Link' ),
     414                'page_label'             => get_post_type_object( 'page' )->labels->singular_name,
     415                /* translators: %s:      menu location */
     416                'menuLocation'           => _x( '(Currently set to: %s)', 'menu' ),
     417                'locationsDescription'   => $locations_description,
     418                'menuNameLabel'          => __( 'Menu Name' ),
     419                'newMenuNameDescription' => __( 'If your theme has multiple menus, giving them clear names will help you manage them.' ),
     420                'itemAdded'              => __( 'Menu item added' ),
     421                'itemDeleted'            => __( 'Menu item deleted' ),
     422                'menuAdded'              => __( 'Menu created' ),
     423                'menuDeleted'            => __( 'Menu deleted' ),
     424                'movedUp'                => __( 'Menu item moved up' ),
     425                'movedDown'              => __( 'Menu item moved down' ),
     426                'movedLeft'              => __( 'Menu item moved out of submenu' ),
     427                'movedRight'             => __( 'Menu item is now a sub-item' ),
    418428                /* translators: ▸ is the unicode right-pointing triangle, and %s is the section title in the Customizer */
    419                 'customizingMenus'  => sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) ),
     429                'customizingMenus'       => sprintf( __( 'Customizing ▸ %s' ), esc_html( $this->manager->get_panel( 'nav_menus' )->title ) ),
    420430                /* translators: %s: title of menu item which is invalid */
    421                 'invalidTitleTpl'   => __( '%s (Invalid)' ),
     431                'invalidTitleTpl'        => __( '%s (Invalid)' ),
    422432                /* translators: %s: title of menu item in draft status */
    423                 'pendingTitleTpl'   => __( '%s (Pending)' ),
    424                 'itemsFound'        => __( 'Number of items found: %d' ),
    425                 'itemsFoundMore'    => __( 'Additional items found: %d' ),
    426                 'itemsLoadingMore'  => __( 'Loading more results... please wait.' ),
    427                 'reorderModeOn'     => __( 'Reorder mode enabled' ),
    428                 'reorderModeOff'    => __( 'Reorder mode closed' ),
    429                 'reorderLabelOn'    => esc_attr__( 'Reorder menu items' ),
    430                 'reorderLabelOff'   => esc_attr__( 'Close reorder mode' ),
     433                'pendingTitleTpl'        => __( '%s (Pending)' ),
     434                'itemsFound'             => __( 'Number of items found: %d' ),
     435                'itemsFoundMore'         => __( 'Additional items found: %d' ),
     436                'itemsLoadingMore'       => __( 'Loading more results... please wait.' ),
     437                'reorderModeOn'          => __( 'Reorder mode enabled' ),
     438                'reorderModeOff'         => __( 'Reorder mode closed' ),
     439                'reorderLabelOn'         => esc_attr__( 'Reorder menu items' ),
     440                'reorderLabelOff'        => esc_attr__( 'Close reorder mode' ),
    431441            ),
    432442            'settingTransport'     => 'postMessage',
     
    538548        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Control' );
    539549        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Name_Control' );
     550        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Locations_Control' );
    540551        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Auto_Add_Control' );
    541552        $this->manager->register_control_type( 'WP_Customize_Nav_Menu_Item_Control' );
     
    559570        // Menu locations.
    560571        $locations     = get_registered_nav_menus();
    561         $num_locations = count( array_keys( $locations ) );
     572        $num_locations = count( $locations );
    562573        if ( 1 == $num_locations ) {
    563             $description = '<p>' . __( 'Your theme supports one menu. Select which menu you would like to use.' ) . '</p>';
     574            $description = '<p>' . __( 'Your theme can display menus in one location. Select which menu you would like to use.' ) . '</p>';
    564575        } else {
    565576            /* translators: %s: number of menu locations */
    566             $description = '<p>' . sprintf( _n( 'Your theme supports %s menu. Select which menu appears in each location.', 'Your theme supports %s menus. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>';
    567         }
     577            $description = '<p>' . sprintf( _n( 'Your theme can display menus in %s location. Select which menu you would like to use.', 'Your theme can display menus in %s locations. Select which menu appears in each location.', $num_locations ), number_format_i18n( $num_locations ) ) . '</p>';
     578        }
     579
    568580        if ( current_theme_supports( 'widgets' ) ) {
    569581            /* translators: URL to the widgets panel of the customizer */
    570             $description .= '<p>' . sprintf( __( 'You can also place menus in <a href="%s">widget areas</a> with the &#8220;Custom Menu&#8221; widget.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>';
     582            $description .= '<p>' . sprintf( __( 'If your theme has widget areas, you can also add menus there. Visit the <a href="%s">Widgets panel</a> and add a &#8220;Custom Menu widget&#8221; to display a menu in a sidebar or footer.' ), "javascript:wp.customize.panel( 'widgets' ).focus();" ) . '</p>';
    571583        }
    572584
    573585        $this->manager->add_section( 'menu_locations', array(
    574             'title'       => __( 'Menu Locations' ),
    575             'panel'       => 'nav_menus',
    576             'priority'    => 5,
    577             'description' => $description,
     586            'title'         => __( 'View All Locations' ),
     587            'panel'         => 'nav_menus',
     588            'priority'      => 30,
     589            'description'   => $description
    578590        ) );
    579591
     
    668680
    669681        // Add the add-new-menu section and controls.
    670         $this->manager->add_section( new WP_Customize_New_Menu_Section( $this->manager, 'add_menu', array(
    671             'title'    => __( 'Add a Menu' ),
     682        $this->manager->add_section( 'add_menu', array(
     683            'type'     => 'new_menu',
     684            'title'    => __( 'New Menu' ),
    672685            'panel'    => 'nav_menus',
    673             'priority' => 999,
    674         ) ) );
    675 
    676         $this->manager->add_control( 'new_menu_name', array(
    677             'label'       => __( 'New menu name' ),
    678             'section'     => 'add_menu',
    679             'type'        => 'text',
    680             'settings'    => array(),
    681             'input_attrs' => array(
    682                 'class'       => 'menu-name-field',
    683             ),
     686            'priority' => 20,
    684687        ) );
    685 
    686         $this->manager->add_control( new WP_Customize_New_Menu_Control( $this->manager, 'create_new_menu', array(
    687             'section'  => 'add_menu',
    688             'settings' => array(),
    689         ) ) );
    690688
    691689        $this->manager->add_setting( new WP_Customize_Filter_Setting( $this->manager, 'nav_menus_created_posts', array(
     
    925923                ?>
    926924            </div>
     925        </script>
     926
     927        <script type="text/html" id="tmpl-nav-menu-delete-button">
     928            <div class="menu-delete-item">
     929                <button type="button" class="button-link button-link-delete">
     930                    <?php _e( 'Delete Menu' ); ?>
     931                </button>
     932            </div>
     933        </script>
     934
     935        <script type="text/html" id="tmpl-nav-menu-submit-new-button">
     936            <p id="customize-new-menu-submit-description"><?php _e( 'Click "next" to start adding links to your new menu.' ); ?></p>
     937            <button id="customize-new-menu-submit" type="button" class="button" aria-describedby="customize-new-menu-submit-description"><?php _e( 'Next' ); ?></button>
     938        </script>
     939
     940        <script type="text/html" id="tmpl-nav-menu-locations-header">
     941            <span class="customize-control-title customize-section-title-menu_locations-heading"><?php _e( 'Menu Locations' ); ?></span>
     942            <p class="customize-control-description customize-section-title-menu_locations-description">{{ data.l10n.locationsDescription }}</p>
     943        </script>
     944
     945        <script type="text/html" id="tmpl-nav-menu-create-menu-section-title">
     946            <h3>
     947                <button type="button" class="button customize-add-menu-button">
     948                    <?php _e( 'Create New Menu' ); ?>
     949                </button>
     950            </h3>
    927951        </script>
    928952    <?php
  • trunk/src/wp-includes/class-wp-customize-section.php

    r41390 r41768  
    386386/** WP_Customize_Nav_Menu_Section class */
    387387require_once( ABSPATH . WPINC . '/customize/class-wp-customize-nav-menu-section.php' );
    388 
    389 /** WP_Customize_New_Menu_Section class */
    390 require_once( ABSPATH . WPINC . '/customize/class-wp-customize-new-menu-section.php' );
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-auto-add-control.php

    r41162 r41768  
    3939    protected function content_template() {
    4040        ?>
     41        <# var elementId = _.uniqueId( 'customize-nav-menu-auto-add-control-' ); #>
    4142        <span class="customize-control-title"><?php _e( 'Menu Options' ); ?></span>
    42         <label>
    43             <input type="checkbox" class="auto_add" />
    44             <?php _e( 'Automatically add new top-level pages to this menu' ); ?>
    45         </label>
     43        <span class="customize-inside-control-row">
     44            <input id="{{ elementId }}" type="checkbox" class="auto_add" />
     45            <label for="{{ elementId }}">
     46                <?php _e( 'Automatically add new top-level pages to this menu' ); ?>
     47            </label>
     48        </span>
    4649        <?php
    4750    }
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-control.php

    r41740 r41768  
    2424
    2525    /**
    26      * The nav menu setting.
    27      *
    28      * @since 4.3.0
    29      * @var WP_Customize_Nav_Menu_Setting
    30      */
    31     public $setting;
    32 
    33     /**
    3426     * Don't render the control's content - it uses a JS template instead.
    3527     *
     
    4537    public function content_template() {
    4638        ?>
    47         <# var elementId; #>
    48         <button type="button" class="button add-new-menu-item" aria-label="<?php esc_attr_e( 'Add or remove menu items' ); ?>" aria-expanded="false" aria-controls="available-menu-items">
    49             <?php _e( 'Add Items' ); ?>
    50         </button>
    51         <button type="button" class="button-link reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder menu items' ); ?>" aria-describedby="reorder-items-desc-{{ data.menu_id }}">
    52             <span class="reorder"><?php _e( 'Reorder' ); ?></span>
    53             <span class="reorder-done"><?php _e( 'Done' ); ?></span>
    54         </button>
     39        <p class="new-menu-item-invitation"><?php _e( 'Time to add some links! Click "Add menu items" to start putting pages, categories, and custom links in your menu. Add as many things as you\'d like.' ); ?></p>
     40        <div class="customize-control-nav_menu-buttons">
     41            <button type="button" class="button add-new-menu-item" aria-label="<?php esc_attr_e( 'Add or remove menu items' ); ?>" aria-expanded="false" aria-controls="available-menu-items">
     42                <?php _e( 'Add Items' ); ?>
     43            </button>
     44            <button type="button" class="button-link reorder-toggle" aria-label="<?php esc_attr_e( 'Reorder menu items' ); ?>" aria-describedby="reorder-items-desc-{{ data.menu_id }}">
     45                <span class="reorder"><?php _e( 'Reorder' ); ?></span>
     46                <span class="reorder-done"><?php _e( 'Done' ); ?></span>
     47            </button>
     48        </div>
    5549        <p class="screen-reader-text" id="reorder-items-desc-{{ data.menu_id }}"><?php _e( 'When in reorder mode, additional controls to reorder menu items will be available in the items list above.' ); ?></p>
    56         <span class="menu-delete-item">
    57             <button type="button" class="button-link button-link-delete">
    58                 <?php _e( 'Delete Menu' ); ?>
    59             </button>
    60         </span>
    61         <?php if ( current_theme_supports( 'menus' ) ) : ?>
    62         <ul class="menu-settings">
    63             <li class="customize-control">
    64                 <span class="customize-control-title"><?php _e( 'Display Location' ); ?></span>
    65             </li>
    66 
    67             <?php foreach ( get_registered_nav_menus() as $location => $description ) : ?>
    68                 <# elementId = _.uniqueId( 'customize-nav-menu-control-location-' ); #>
    69                 <li class="customize-control customize-control-checkbox assigned-menu-location customize-inside-control-row">
    70                     <input id="{{ elementId }}" type="checkbox" data-menu-id="{{ data.menu_id }}" data-location-id="<?php echo esc_attr( $location ); ?>" class="menu-location" />
    71                     <label for="{{ elementId }}">
    72                         <?php echo $description; ?>
    73                         <span class="theme-location-set">
    74                             <?php
    75                             /* translators: %s: menu name */
    76                             printf( _x( '(Current: %s)', 'menu location' ),
    77                                 '<span class="current-menu-location-name-' . esc_attr( $location ) . '"></span>'
    78                             );
    79                             ?>
    80                         </span>
    81                     </label>
    82                 </li>
    83             <?php endforeach; ?>
    84         </ul>
    85         <?php endif; ?>
    8650        <?php
    8751    }
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menu-name-control.php

    r41162 r41768  
    4141        <label>
    4242            <# if ( data.label ) { #>
    43                 <span class="customize-control-title screen-reader-text">{{ data.label }}</span>
     43                <span class="customize-control-title">{{ data.label }}</span>
    4444            <# } #>
    45             <input type="text" class="menu-name-field live-update-section-title" />
     45            <input type="text" class="menu-name-field live-update-section-title"
     46                <# if ( data.description ) { #>
     47                    aria-describedby="{{ data.section }}-description"
     48                <# } #>
     49                />
    4650        </label>
     51        <# if ( data.description ) { #>
     52            <p id="{{ data.section }}-description">{{ data.description }}</p>
     53        <# } #>
    4754        <?php
    4855    }
  • trunk/src/wp-includes/customize/class-wp-customize-nav-menus-panel.php

    r41162 r41768  
    9393            </div>
    9494        </li>
     95        <?php
     96        // NOTE: The following is a workaround for an inability to treat (and thus label) a list of sections as a whole.
     97        ?>
     98        <li class="customize-control-title customize-section-title-nav_menus-heading"><?php _e( 'Menus' ); ?></li>
    9599    <?php
    96100    }
  • trunk/tests/qunit/wp-admin/js/customize-nav-menus.js

    r38049 r41768  
    6666        ok( controls[0].extended( api.Menus.MenuNameControl ), 'first control in menu section is MenuNameControl' );
    6767        ok( controls[1].extended( api.Menus.MenuItemControl ), 'second control in menu section is MenuItemControl' );
    68         ok( controls[ controls.length - 1 ].extended( api.Menus.MenuAutoAddControl ), 'last control in menu section is a MenuAutoAddControl' );
     68        ok( controls[ controls.length - 1 ].extended( api.Menus.MenuDeleteControl ), 'last control in menu section is a MenuDeleteControl' );
    6969    } );
    7070    // @todo Add more tests for api.Menus.MenuSection behaviors
Note: See TracChangeset for help on using the changeset viewer.