Customize: Introduce starter content and site freshness state.

A theme can opt-in for tailored starter content to apply to the customizer when previewing the theme on a fresh install, when `fresh_site` is at its initial `1` value. Starter content is staged in the customizer and does not go live unless the changes are published. Initial starter content is added to Twenty Seventeen.

* The `fresh_site` flag is cleared when a published post or page is saved, when widgets are modified, or when the customizer state is saved.
* Starter content is registered via `starter-content` theme support, where the argument is an array containing `widgets`, `posts`, `nav_menus`, `options`, and `theme_mods`. Posts/pages in starter content are created with the `auto-draft` status, re-using the page/post stubs feature added to nav menus and the static front page controls.
* A `get_theme_starter_content` filter allows for plugins to extend a theme's starter content.
* Starter content in themes can/should re-use existing starter content items in core by using named placeholders.
* Import theme starter content into customized state when fresh site.
* Prevent original_title differences from causing refreshes if title is present.
* Ensure nav menu item url is set according to object when previewing.
* Make sure initial saved state is false if there are dirty settings without an existing changeset.
* Ensure dirty settings are cleaned upon changeset publishing.

Props helen, westonruter, ocean90.
Fixes #38114, #38533.

Built from https://develop.svn.wordpress.org/trunk@38991


git-svn-id: http://core.svn.wordpress.org/trunk@38934 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
Weston Ruter
2016-10-28 02:57:35 +00:00
parent 60eb1ddc5c
commit 75535c596b
12 changed files with 434 additions and 10 deletions

View File

@@ -516,6 +516,9 @@ function populate_options() {
// 4.4.0
'medium_large_size_w' => 768,
'medium_large_size_h' => 0,
// 4.7.0
'fresh_site' => 1,
);
// 3.3

View File

@@ -146,7 +146,7 @@
settingRevision = api._latestSettingRevisions[ setting.id ];
// Skip including settings that have already been included in the changeset, if only requesting unsaved.
if ( ( options && options.unsaved ) && ( _.isUndefined( settingRevision ) || settingRevision <= api._lastSavedRevision ) ) {
if ( api.state( 'changesetStatus' ).get() && ( options && options.unsaved ) && ( _.isUndefined( settingRevision ) || settingRevision <= api._lastSavedRevision ) ) {
return;
}
@@ -4880,7 +4880,7 @@
api.bind( 'change', captureSettingModifiedDuringSave );
submit = function () {
var request, query, settingInvalidities = {};
var request, query, settingInvalidities = {}, latestRevision = api._latestRevision;
/*
* Block saving if there are any settings that are marked as
@@ -4984,6 +4984,20 @@
api.state( 'changesetStatus' ).set( response.changeset_status );
if ( 'publish' === response.changeset_status ) {
// Mark all published as clean if they haven't been modified during the request.
api.each( function( setting ) {
/*
* Note that the setting revision will be undefined in the case of setting
* values that are marked as dirty when the customizer is loaded, such as
* when applying starter content. All other dirty settings will have an
* associated revision due to their modification triggering a change event.
*/
if ( setting._dirty && ( _.isUndefined( api._latestSettingRevisions[ setting.id ] ) || api._latestSettingRevisions[ setting.id ] <= latestRevision ) ) {
setting._dirty = false;
}
} );
api.state( 'changesetStatus' ).set( '' );
api.settings.changeset.uuid = response.next_changeset_uuid;
parent.send( 'changeset-uuid', api.settings.changeset.uuid );
@@ -5152,7 +5166,15 @@
});
// Set default states.
changesetStatus( api.settings.changeset.status );
saved( true );
if ( '' === changesetStatus() ) { // Handle case for loading starter content.
api.each( function( setting ) {
if ( setting._dirty ) {
saved( false );
}
} );
}
saving( false );
activated( api.settings.theme.active );
processing( 0 );
@@ -5161,7 +5183,6 @@
expandedSection( false );
previewerAlive( true );
editShortcutVisibility( 'initial' );
changesetStatus( api.settings.changeset.status );
api.bind( 'change', function() {
state('saved').set( false );

File diff suppressed because one or more lines are too long