Opened 8 years ago
Last modified 4 years ago
#38797 new enhancement
api.previewer.refresh() could return a deferred.promise() with custom server data
Reported by: | nikeo | Owned by: | |
---|---|---|---|
Milestone: | Future Release | Priority: | normal |
Severity: | normal | Version: | |
Component: | Customize | Keywords: | has-patch needs-testing |
Focuses: | javascript | Cc: |
Description
Following a discussion (https://core.trac.wordpress.org/ticket/38728#comment:8) with @westonruter, I'd like to propose an enhancement for the api.previewer.refresh(
) method.
There might be cases when a developer needs to fire a previewer refresh after a specific customizer change, and execute other actions when this refresh has been done.
From a general standpoint, I think that the asynchronous nature of the refresh makes it a good candidate for returning a deferred promise.
An example of use case could be that a developer has several predefined settings configuration available for a given theme. Each time a configuration is switched to, the settings have to be changed to a set of predefined values set in the api. Those predefined values are stored server side in say a custom post type ( like the changeset for ex. ).
A way to do that would be to fire an api.previewer.refresh()
when switching to a given predefined configuration, that would be followed on api.previewer.refresh().done( ... )
by an update of the api values, if some conditions are met.
With the current api, we can add callbacks to the 'synced'
previewer event, but it will be fired on all api.previewer.refresh()
calls, with no possibility to target a specific refresh situation that should be followed by a custom action.
This problem could be solved by making the refresh return a deferred promise. This $.Deferred() would be resolve() in the onceSynced()
callback function (of the current refreh method), taking a sent_preview_data
object as param.
While this deferred would be implemented in the api.previewer.refresh(
) method of customize-control.js, another minor addition in customize-preview.js could allow developers to easily pass custom server data on refresh to the panel this way, and then use those data once the refresh is done.
This way, it would be possible to use the following kind of syntax to fire an action on demand after a specific refresh().
api.previewer.refresh().done( function( sent_preview_data ) { // fire actions after a specific refresh, when the preview is ready and synced // the sent_preview_data, could be an object sent when the api.preview.send( 'synced', preview_data() ), // providing customizable server informations that we may need after a refresh. } );
On the preview side, in order to pass a server data object to the resolve refresh, the idea would be to introduce a new api.Value()
that could be populated before the synced event occurence.
The current code in [customize-preview.js]https://core.trac.wordpress.org/browser/trunk/src/wp-includes/js/customize-preview.js#L679 :
api.preview.send( 'synced');
could be replaced by :
api.server_data = api.server_data || new api.Value( {} ); api.trigger('before_synced', api.server_data() );//<= developers can alter the api.server_data() here, before it gets sent api.preview.send( 'synced', api.server_data() );
This way, a developer could pass custom data to the panel when api.previewer.refresh().done()
, using the synced
event, with this type of code :
<?php add_action('wp_footer', function() { if ( ! is_customize_preview() ) return; ?> <script type="text/javascript"> jQuery( function( $ ) { wp.customize.bind( 'before_synced', function( value ) { //the developer sets the server_data here, before it is sent to the preview wp.customize.server_data( { custom_data : <?php echo get_custom_data(); ?> } ); } ); } ); </script> <?php });
Attachments (3)
Change History (7)
#1
@
8 years ago
- Keywords needs-patch added
- Milestone changed from Awaiting Review to Future Release
#3
@
8 years ago
@celloexpressions this is a proposition of implementation for the refresh promise.
I've also created a small plugin to test it with TwentySeventeen : https://gist.github.com/Nikeo/86eeff438fb6e23b1da0a74a89dd8199
Changes in wp-admin/customize-control.js :
I had to adapt the original debounced refresh because _.debounce
won't work properly with a promise object. The proposed code should normally do the same job with setTimeout
. The originaRefresh.call( previewer )
is now replaced by api.Previewer.prototype.refresh.call( previewer )
The onceSynced
event now takes the server_data
as params and resolves the $.Deferred
object with it.
Changes in wp-includes/customize-preview.js :
The idea is to allow developer to hook on the synced
event, and send for example contextual informations to the panel.
I have introduced a new api.Value to store those data : api.server_data()
and a before_synced
event to set it.
The gist example illustrates a possible use of this code to send the post informations to the panel in a is_singular context.
This sounds good to me. Can you create a patch with your proposed changes @nikeo?