Make WordPress Core

Changeset 41389


Ignore:
Timestamp:
09/19/2017 12:45:23 AM (9 years ago)
Author:
westonruter
Message:

Customize: Show notification error with "Your homepage displays" control when homepage and posts page are set to be the same (but not empty).

  • Show global error notiafication when saving is blocked due to client-side setting invalidity.
  • Refactor wp.customize.Notifications#render() to ensure a notification re-renders if its message or data changes but its code does not.

Props MatheusGimenez, sixhours, westonruter, karmatosed, aocean90, zoonini, michelleweber, melchoyce.
See #35210.
Fixes #21492.

Location:
trunk/src
Files:
3 edited

Legend:

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

    r41376 r41389  
    842842
    843843/**
     844 * Static front page
     845 */
     846
     847#customize-control-show_on_front.has-error {
     848        margin-bottom: 0;
     849}
     850#customize-control-show_on_front.has-error .customize-control-notifications-container {
     851        margin-top:12px;
     852}
     853
     854/**
    844855 * Dropdowns
    845856 */
  • trunk/src/wp-admin/js/customize-controls.js

    r41376 r41389  
    147147                        var collection = this,
    148148                                notifications,
    149                                 renderedNotificationContainers,
    150                                 prevRenderedCodes,
    151                                 nextRenderedCodes,
    152                                 addedCodes,
    153                                 removedCodes,
     149                                previousNotificationsByCode = {},
    154150                                listElement;
    155151
     
    158154                                return;
    159155                        }
     156
     157                        notifications = collection.get( { sort: true } );
     158                        collection.container.toggle( 0 !== notifications.length );
     159
     160                        // Short-circuit if there are no changes to the notifications.
     161                        if ( _.isEqual( notifications, collection.previousNotifications ) ) {
     162                                return;
     163                        }
     164
     165                        // Make sure list is part of the container.
    160166                        listElement = collection.container.children( 'ul' ).first();
    161167                        if ( ! listElement.length ) {
     
    164170                        }
    165171
    166                         notifications = collection.get( { sort: true } );
    167 
    168                         renderedNotificationContainers = {};
    169                         listElement.find( '> [data-code]' ).each( function() {
    170                                 renderedNotificationContainers[ $( this ).data( 'code' ) ] = $( this );
    171                         });
    172 
    173                         collection.container.toggle( 0 !== notifications.length );
    174 
    175                         nextRenderedCodes = _.pluck( notifications, 'code' );
    176                         prevRenderedCodes = _.keys( renderedNotificationContainers );
    177 
    178                         // Short-circuit if there are no notifications added.
    179                         if ( _.isEqual( nextRenderedCodes, prevRenderedCodes ) ) {
    180                                 return;
    181                         }
    182 
    183                         addedCodes = _.difference( nextRenderedCodes, prevRenderedCodes );
    184                         removedCodes = _.difference( prevRenderedCodes, nextRenderedCodes );
    185 
    186                         // Remove notifications that have been removed.
    187                         _.each( renderedNotificationContainers, function( renderedContainer, code ) {
    188                                 if ( -1 !== _.indexOf( removedCodes, code ) ) {
    189                                         renderedContainer.remove(); // @todo Consider slideUp as enhancement.
    190                                 }
     172                        // Remove all notifications prior to re-rendering.
     173                        listElement.find( '> [data-code]' ).remove();
     174
     175                        _.each( collection.previousNotifications, function( notification ) {
     176                                previousNotificationsByCode[ notification.code ] = notification;
    191177                        });
    192178
    193179                        // Add all notifications in the sorted order.
    194180                        _.each( notifications, function( notification ) {
    195                                 var notificationContainer = renderedNotificationContainers[ notification.code ];
    196                                 if ( notificationContainer ) {
    197                                         listElement.append( notificationContainer );
    198                                 } else {
    199                                         notificationContainer = $( notification.render() );
    200                                         listElement.append( notificationContainer ); // @todo Consider slideDown() as enhancement.
    201                                         if ( wp.a11y ) {
    202                                                 wp.a11y.speak( notification.message, 'assertive' );
    203                                         }
    204                                 }
    205                         });
    206 
     181                                if ( wp.a11y && ( ! previousNotificationsByCode[ notification.code ] || ! _.isEqual( notification.message, previousNotificationsByCode[ notification.code ].message ) ) ) {
     182                                        wp.a11y.speak( notification.message, 'assertive' );
     183                                }
     184                                listElement.append( $( notification.render() ) ); // @todo Consider slideDown() as enhancement.
     185                        });
     186
     187                        collection.previousNotifications = notifications;
    207188                        collection.trigger( 'rendered' );
    208189                }
     
    46454626
    46464627                                submit = function () {
    4647                                         var request, query, settingInvalidities = {}, latestRevision = api._latestRevision;
     4628                                        var request, query, settingInvalidities = {}, latestRevision = api._latestRevision, errorCode = 'client_side_error';
    46484629
    46494630                                        api.bind( 'change', captureSettingModifiedDuringSave );
     4631                                        api.notifications.remove( errorCode );
    46504632
    46514633                                        /*
     
    46694651                                                _.values( invalidControls )[0][0].focus();
    46704652                                                api.unbind( 'change', captureSettingModifiedDuringSave );
     4653
     4654                                                api.notifications.add( errorCode, new api.Notification( errorCode, {
     4655                                                        message: ( 1 === invalidSettings.length ? api.l10n.saveBlockedError.singular : api.l10n.saveBlockedError.plural ).replace( /%s/g, String( invalidSettings.length ) ),
     4656                                                        type: 'error',
     4657                                                        dismissible: true,
     4658                                                        saveFailure: true
     4659                                                } ) );
     4660
    46714661                                                deferred.rejectWith( previewer, [
    46724662                                                        { setting_invalidities: settingInvalidities }
     
    56115601                });
    56125602
    5613                 // Change previewed URL to the homepage when changing the page_on_front.
    5614                 api( 'show_on_front', 'page_on_front', function( showOnFront, pageOnFront ) {
    5615                         var updatePreviewUrl = function() {
    5616                                 if ( showOnFront() === 'page' && parseInt( pageOnFront(), 10 ) > 0 ) {
    5617                                         api.previewer.previewUrl.set( api.settings.url.home );
     5603                // Add behaviors to the static front page controls.
     5604                api( 'show_on_front', 'page_on_front', 'page_for_posts', function( showOnFront, pageOnFront, pageForPosts ) {
     5605                        var handleChange = function() {
     5606                                var setting = this, pageOnFrontId, pageForPostsId, errorCode = 'show_on_front_page_collision';
     5607                                pageOnFrontId = parseInt( pageOnFront(), 10 );
     5608                                pageForPostsId = parseInt( pageForPosts(), 10 );
     5609
     5610                                if ( 'page' === showOnFront() ) {
     5611
     5612                                        // Change previewed URL to the homepage when changing the page_on_front.
     5613                                        if ( setting === pageOnFront && pageOnFrontId > 0 ) {
     5614                                                api.previewer.previewUrl.set( api.settings.url.home );
     5615                                        }
     5616
     5617                                        // Change the previewed URL to the selected page when changing the page_for_posts.
     5618                                        if ( setting === pageForPosts && pageForPostsId > 0 ) {
     5619                                                api.previewer.previewUrl.set( api.settings.url.home + '?page_id=' + pageForPostsId );
     5620                                        }
     5621                                }
     5622
     5623                                // Toggle notification when the homepage and posts page are both set and the same.
     5624                                if ( 'page' === showOnFront() && pageOnFrontId && pageForPostsId && pageOnFrontId === pageForPostsId ) {
     5625                                        showOnFront.notifications.add( errorCode, new api.Notification( errorCode, {
     5626                                                type: 'error',
     5627                                                message: api.l10n.pageOnFrontError
     5628                                        } ) );
     5629                                } else {
     5630                                        showOnFront.notifications.remove( errorCode );
    56185631                                }
    56195632                        };
    5620                         showOnFront.bind( updatePreviewUrl );
    5621                         pageOnFront.bind( updatePreviewUrl );
    5622                 });
    5623 
    5624                 // Change the previewed URL to the selected page when changing the page_for_posts.
    5625                 api( 'page_for_posts', function( setting ) {
    5626                         setting.bind(function( pageId ) {
    5627                                 pageId = parseInt( pageId, 10 );
    5628                                 if ( pageId > 0 ) {
    5629                                         api.previewer.previewUrl.set( api.settings.url.home + '?page_id=' + pageId );
    5630                                 }
     5633                        showOnFront.bind( handleChange );
     5634                        pageOnFront.bind( handleChange );
     5635                        pageForPosts.bind( handleChange );
     5636                        handleChange.call( showOnFront, showOnFront() ); // Make sure initial notification is added after loading existing changeset.
     5637
     5638                        // Move notifications container to the bottom.
     5639                        api.control( 'show_on_front', function( showOnFrontControl ) {
     5640                                showOnFrontControl.deferred.embedded.done( function() {
     5641                                        showOnFrontControl.container.append( showOnFrontControl.getNotificationsContainerElement() );
     5642                                });
    56315643                        });
    56325644                });
  • trunk/src/wp-includes/script-loader.php

    r41376 r41389  
    571571                        array( 'singular', 'plural' )
    572572                ),
     573                'pageOnFrontError' => __( 'Homepage and posts page must be different.' ),
     574                'saveBlockedError' => wp_array_slice_assoc(
     575                        /* translators: placeholder is error count */
     576                        _n_noop( 'Unable to save due to %s invalid setting.', 'Unable to save due to %s invalid settings.' ),
     577                        array( 'singular', 'plural' )
     578                ),
    573579        ) );
    574580        $scripts->add( 'customize-selective-refresh', "/wp-includes/js/customize-selective-refresh$suffix.js", array( 'jquery', 'wp-util', 'customize-preview' ), false, 1 );
Note: See TracChangeset for help on using the changeset viewer.