External Live Previews For Themes
The Live Preview buttons, on the /wp-admin/themes.php
page, are generated from the tmpl-theme micro template:
<script id="tmpl-wpse" type="text/template">
...cut...
<div class="theme-actions">
<# if ( data.active ) { #>
<# if ( data.actions.customize ) { #>
<a class="button button-primary customize load-customize hide-if-no-customize" href="https://wordpress.stackexchange.com/questions/220473/{{{ data.actions.customize }}}"><?php _e( 'Customize' ); ?></a>
<# } #>
<# } else { #>
<a class="button button-secondary activate" href="{{{ data.actions.activate }}}"><?php _e( 'Activate' ); ?></a>
<a class="button button-primary load-customize hide-if-no-customize" href="https://wordpress.stackexchange.com/questions/220473/{{{ data.actions.customize }}}"><?php _e( 'Live Preview' ); ?></a>
<# } #>
</div>
...cut...
</script>
We can modify the template data via the wp_prepare_themes_for_js
filter.
Here’s an example:
/**
* External Live Previews
*/
add_filter( 'wp_prepare_themes_for_js', function( $prepared_themes )
{
//--------------------------
// Edit this to your needs:
$externals = [
'twentysixteen' => 'http://foo.tld/demo/twentysixteen/',
'twentyfifteen' => 'http://bar.tld/demo/twentyfifteen/'
];
//--------------------------
foreach( $externals as $slug => $url )
{
if( isset( $prepared_themes[$slug]['actions']['customize'] ) )
$prepared_themes[$slug]['actions']['customize'] = $url;
}
return $prepared_themes;
} );
But this will not work as expected, because of the load-customize
class, that will trigger a click event and open up an iframe overlay with:
$('#wpbody').on( 'click', '.load-customize', function( event ) {
event.preventDefault();
// Store a reference to the link that opened the Customizer.
Loader.link = $(this);
// Load the theme.
Loader.open( Loader.link.attr('href') );
});
When we click on the Live Preview button, with an external url, it will trigger an error like:
Uncaught SecurityError: Failed to execute ‘
pushState
‘ on ‘History’: A
history state object with URL ‘http://foo.tld/demo/twentysixteen/
‘
cannot be created in a document with origin ‘http://example.tld
‘ and
URL ‘http://example.tld/wp-admin/themes.php
‘.
We could prevent this, by double clicking (not really a reliable option) or by removing the load-customize
class for the external preview links. Here’s one such hack:
/**
* Remove the .load-customize class from buttons with external links
*/
add_action( 'admin_print_styles-themes.php', function()
{ ?>
<script>
jQuery(document).ready( function($) {
$('.load-customize').each( function( index ){
if( this.host !== window.location.host )
$( this ).removeClass( 'load-customize' );
} );
});
</script> <?php
} );
where I got the this.host
idea from @daved here.
Another more drastic approach would be to override the tmpl-theme
template.