[wp-trac] [WordPress Trac] #30937: Add Customizer changesets (state persistance) (was: Add Customizer transactions)

WordPress Trac noreply at wordpress.org
Sun Oct 2 07:48:32 UTC 2016


#30937: Add Customizer changesets (state persistance)
-----------------------------+--------------------------
 Reporter:  westonruter      |       Owner:  westonruter
     Type:  feature request  |      Status:  assigned
 Priority:  high             |   Milestone:  4.7
Component:  Customize        |     Version:
 Severity:  normal           |  Resolution:
 Keywords:  has-patch        |     Focuses:
-----------------------------+--------------------------
Changes (by westonruter):

 * keywords:  needs-patch => has-patch


Old description:

> The existence of modified settings in the Customizer is restricted to a
> browser window. When a user changes a control in the Customizer and a
> setting is thus modified, the changed setting is sent to the Customizer
> preview either by JavaScript (`postMessage`), or an Ajax POST request is
> made to the URL being previewed with the `customized` data sent along,
> and then this incoming `$_POST` data is added to filters so that the
> changes are reflected when WordPress builds the page to display in the
> preview iframe.
>
> A downside to this current approach is that if the user navigates away
> from the Customizer, they lose their settings. To get around this, we
> added an AYS dialog in #25439, but this still doesn't account for browser
> crashes or system failures.
>
> Another downside is that whenever the preview needs to load a new URL it
> has to re-send all the modified settings so that the Customizer preview
> will have them available to add to the filters, since the Customized data
> is not persisted in WordPress in any way. There's also a performance hit
> to continually send all data with each request, which was partially
> improved with #28580.
>
> So I propose that we introduce persisted Customizer settings, in other
> words '''Customizer transactions'''.
>
> When opening the Customizer for the first time, a transaction UUID can be
> generated. Whenever a setting changes, an Ajax request sends the updated
> setting to WordPress to be persisted in a `wp_transaction` post which has
> a post_name corresponding to that UUID (or a post is created dynamically
> if not existing already). Any changes made in the Customizer then get
> amended to the same `wp_transaction` post, which has a key/value JSON
> blob as its `post_content`.
>
> Instead of POSTing all of the customized settings to the preview, we then
> only have to reference the transaction UUID when loading URLs into the
> Customizer preview. Indeed, the patch I've worked on does this in a way
> that resolves #30028 (Load Customizer preview iframe with natural URL)
> and #23225 by injecting the transaction UUID as a query parameter for the
> URL being previewed and then amended to any site URL generated in the
> preview, so that navigating around the site in the preview (even
> following standard links with `GET` requests) will ensure that the
> transaction will continue to be referenced and loaded. In this way, when
> a transaction is updated the Customizer preview only has to do
> `location.reload()` instead of the current approach of doing an Ajax POST
> request followed by `document.write()` in the iframe window.
>
> As noted in #20714, my patch also injects the transaction UUID in form
> submissions (GET and POST), as well as in jQuery Ajax requests. This
> allows you to preview setting changes for full web applications in the
> Customizer.
>
> Other side-benefits that Customizer transactions will bring us:
>
>  * Settings can be drafted and then returned to later.
>  * Settings can be collaborated on by multiple users (though not
> concurrently, without some Heartbeat system in place)
>  * The capability to publish a `wp_transaction` post can be limited by
> role, allowing 'Customizer contributors' to submit settings as pending
> review.
>  * Settings can be scheduled for going live at a later date by saving the
> transaction post simply with `post_status=future` (see #28721)
>  * With each save in the Customizer resulting in a new transaction post
> being created, then there is Customizer revision history (see #31088,
> #31089)
>  * Accessing the Customizer preview for a transaction needs no special
> capabilities since the transaction is updated by an authorized user via
> single Ajax request. This means that Customizer previews (frontend URLs
> with the transaction UUID amended) can be shared for anonymous users to
> review.
>  * Customizer Theme Switch (#31303) could preview another theme and
> refresh the Customizer without losing settings, and thus no AYS dialog
> would be needed.
>
> Something else that motivated my investigation into Customizer
> transactions is thinking about how the Customizer will relate to the
> '''JSON REST API'''. How can the REST API be improved with the
> Customizer? If the REST API provides a `transactions` endpoint for doing
> CRUD operations on Customizer settings, and if the REST API also has
> global recognition for a `customize_transaction_uuid` query parameter in
> all requests, then it becomes possible for the Customizer to be used to
> preview changes in applications that merely interact with the JSON REST
> API, as long as they include the transaction UUID in the requests.
>
> There's a lot of exciting possibilities introduced with Customizer
> transactions.
>
> Initial alpha Core patch for Customizer transactions can be seen at:
> https://github.com/xwp/wordpress-develop/pull/61
>
> See Make Core blog post: https://make.wordpress.org/core/2015/01/26
> /customizer-transactions-proposal/
>
> Related:
>  * #30028: Load Customizer preview iframe with natural URL
>  * #30936: Dynamically create WP_Customize_Settings for settings created
> on JS client
>  * #27355: Customizer: Add framework for partial preview refreshes
>  * #20714: Theme customizer: Impossible to preview a search results page
>  * #23225: Customizer is Incompatible with jQuery UI Tabs.
>  * #28721: Scheduled changes for the customizer
>  * #31088/#31089: Customizer revisions
>  * #31517: Customizer: show a notice after attempting to navigate to
> external links in live previews
>  * #34893: Improve Customizer setting validation model
>  * #34142: Links with preventDefault() don't have action prevented in
> Customizer
>  * #28227: Customizer: Error message instead of blank screen
>  * #31641: Theme Preview using "Customize.php" error
>  * #22037: Customizer: Live preview fetches page but does not display
>  * #36485: Lost pending customizer settings after theme change

New description:

 The existence of modified settings in the Customizer is restricted to a
 browser window. When a user changes a control in the Customizer and a
 setting is thus modified, the changed setting is sent to the Customizer
 preview either by JavaScript (`postMessage`), or an Ajax POST request is
 made to the URL being previewed with the `customized` data sent along, and
 then this incoming `$_POST` data is added to filters so that the changes
 are reflected when WordPress builds the page to display in the preview
 iframe.

 A downside to this current approach is that if the user navigates away
 from the Customizer, they lose their settings. To get around this, we
 added an AYS dialog in #25439, but this still doesn't account for browser
 crashes or system failures.

 Another downside is that whenever the preview needs to load a new URL it
 has to re-send all the modified settings so that the Customizer preview
 will have them available to add to the filters, since the Customized data
 is not persisted in WordPress in any way. There's also a performance hit
 to continually send all data with each request, which was partially
 improved with #28580.
 I
 So I propose that we introduce persisted Customizer settings, in other
 words '''Customizer ~~transactions~~ changesets'''.

 When opening the Customizer for the first time, a changeset UUID can be
 generated. Whenever a setting changes, an Ajax request sends the updated
 setting to WordPress to be persisted in a `customize_changeset` post which
 has a post_name corresponding to that UUID (or a post is created
 dynamically if not existing already). Any changes made in the Customizer
 then get amended to the same `customize_changeset` post, which has a
 key/value JSON blob as its `post_content`.

 Instead of POSTing all of the customized settings to the preview, we then
 only have to reference the changeset UUID when loading URLs into the
 Customizer preview. Indeed, the patch I've worked on does this in a way
 that resolves #30028 (Load Customizer preview iframe with natural URL) and
 #23225 by injecting the changeset UUID as a query parameter for the URL
 being previewed and then amended to any site URL generated in the preview,
 so that navigating around the site in the preview (even following standard
 links with `GET` requests) will ensure that the changeset will continue to
 be referenced and loaded. In this way, when a changeset is updated the
 Customizer preview only has to do `location.reload()` instead of the
 current approach of doing an Ajax POST request followed by
 `document.write()` in the iframe window. (Nevertheless, the existing
 “seamless refresh” logic can remaij in which a loading `PreviewIframe`
 instance can replace the previously loaded one after it has finished
 loaded.)

 As noted in #20714, my patch also injects the changeset UUID in form
 submissions (GET and POST), as well as in jQuery Ajax requests. This
 allows you to preview setting changes for full web applications in the
 Customizer.

 Other side-benefits that Customizer changesets will bring us:

  * Settings can be drafted and then returned to later.
  * Settings can be collaborated on by multiple users (though not
 concurrently, without some Heartbeat system in place)
  * The capability to publish a `customize_changeset` post can be limited
 by role, allowing 'Customizer contributors' to submit settings as pending
 review.
  * Settings can be scheduled for going live at a later date by saving the
 changeset post simply with `post_status=future` (see #28721)
  * With each save in the Customizer resulting in a new changeset post
 being created, then there is Customizer revision history (see #31088,
 #31089)
  * Accessing the Customizer preview for a changeset needs no special
 capabilities since the changeset is updated by an authorized user via
 single Ajax request. This means that Customizer previews (frontend URLs
 with the changeset UUID amended) can be shared for anonymous users to
 review.
  * Customizer Theme Switch (#31303) could preview another theme and
 refresh the Customizer without losing settings, and thus no AYS dialog
 would be needed. (See #36485.)

 Something else that motivated my investigation into Customizer changesets
 is thinking about how the Customizer will relate to the '''JSON REST
 API'''. How can the REST API be improved with the Customizer? If the REST
 API provides a `changesets` endpoint for doing CRUD operations on
 Customizer settings, and if the REST API also has global recognition for a
 `customize_changeset_uuid` query parameter in all requests, then it
 becomes possible for the Customizer to be used to preview changes in
 applications that merely interact with the JSON REST API, as long as they
 include the changeset UUID in the requests.

 There's a lot of exciting possibilities introduced with Customizer
 changesets.

 Initial alpha Core patch for Customizer changesets can be seen at:
 https://github.com/xwp/wordpress-develop/pull/61

 See Make Core blog post: https://make.wordpress.org/core/2015/01/26
 /customizer-transactions-proposal/

 Related:
  * #30028: Load Customizer preview iframe with natural URL
  * #30936: Dynamically create WP_Customize_Settings for settings created
 on JS client
  * #27355: Customizer: Add framework for partial preview refreshes
  * #20714: Theme customizer: Impossible to preview a search results page
  * #23225: Customizer is Incompatible with jQuery UI Tabs.
  * #28721: Scheduled changes for the customizer
  * #31088/#31089: Customizer revisions
  * #31517: Customizer: show a notice after attempting to navigate to
 external links in live previews
  * #34893: Improve Customizer setting validation model
  * #34142: Links with preventDefault() don't have action prevented in
 Customizer
  * #28227: Customizer: Error message instead of blank screen
  * #31641: Theme Preview using "Customize.php" error
  * #22037: Customizer: Live preview fetches page but does not display
  * #36485: Lost pending customizer settings after theme change

--

Comment:

 I have a patch for testing! There are still several things I want to
 polish, but please give this PR a try: https://github.com/xwp/wordpress-
 develop/pull/161

 Remember, the patch can be applied via `grunt patch:https://github.com/xwp
 /wordpress-develop/pull/161`

 For collaboration on the patch, please do not amend the patch and upload
 new diffs to this ticket. Open PRs to the `trac-30937` branch on GitHub or
 ask me and I'll set you up with direct push access.

 Note that I've renamed “transactions” to “changesets” which I think makes
 more sense.

 Here's a companion plugin which enables revisions for Changesets and
 provides access to the custom post type's admin screens:
 https://gist.github.com/westonruter/b2c9edb9a2ee83236dd9b2b4f177ae76

--
Ticket URL: <https://core.trac.wordpress.org/ticket/30937#comment:57>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list