Last active
October 1, 2018 11:22
-
-
Save westonruter/26ea57217efc074b2a948e32a61897f9 to your computer and use it in GitHub Desktop.
WPSE 286268: Demonstration of adding controls which are contextual to device previews. https://wordpress.stackexchange.com/a/286294/8521
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<ruleset name="WPSE 286268 Plugin"> | |
<rule ref="WordPress-Core" /> | |
<rule ref="WordPress.WP.I18n"> | |
<properties> | |
<property name="text_domain" value="wpse-286268" /> | |
</properties> | |
</rule> | |
<rule ref="WordPress-Docs" /> | |
<rule ref="WordPress.Arrays.MultipleStatementAlignment.DoubleArrowNotAligned"> | |
<severity>0</severity> | |
</rule> | |
<rule ref="Generic.Formatting.MultipleStatementAlignment.NotSameWarning"> | |
<severity>0</severity> | |
</rule> | |
<rule ref="WordPress.Arrays.ArrayDeclarationSpacing.AssociativeKeyFound"> | |
<severity>0</severity> | |
</rule> | |
<rule ref="WordPress.Files.FileName.InvalidClassFileName"> | |
<exclude-pattern>wpse-286268.php</exclude-pattern> | |
</rule> | |
<arg name="extensions" value="php"/> | |
<arg value="s"/> | |
<file>.</file> | |
<exclude-pattern>*/node_modules/*</exclude-pattern> | |
<exclude-pattern>*/vendor/*</exclude-pattern> | |
<exclude-pattern>*/dev-lib/*</exclude-pattern> | |
</ruleset> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* globals wp */ | |
/* exported wpse286268controls */ | |
var wpse286268controls = ( function( api ) { | |
'use strict'; | |
var component = { | |
deviceControls: {} | |
}; | |
/** | |
* Init. | |
* | |
* @param {object} args - Args. | |
* @param {object} args.deviceControls - Device controls. | |
* @returns {void} | |
*/ | |
component.init = function( args ) { | |
component.deviceControls = args.deviceControls; | |
api.bind( 'ready', component.setControlActiveStates ); | |
}; | |
/** | |
* Set the active states for the device controls. | |
* | |
* @returns {void} | |
*/ | |
component.setControlActiveStates = function() { | |
_.each( component.deviceControls, function( controlId, deviceSlug ) { | |
api.control( controlId, function( control ) { | |
function isActive() { | |
return deviceSlug === api.state( 'previewedDevice' ).get(); | |
} | |
// Set initial active state. | |
control.active.set( isActive ); | |
// Update active state whenever previewd device changes. | |
api.state( 'previewedDevice' ).bind( function() { | |
control.active.set( isActive ); | |
} ); | |
// Override whatever the active_callback may send from server when preview loads. | |
control.active.validate = isActive; | |
} ); | |
} ); | |
}; | |
return component; | |
} )( wp.customize ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* globals wp, jQuery */ | |
/* exported wpse286268preview */ | |
var wpse286268preview = ( function( api, $ ) { | |
'use strict'; | |
var component = { | |
deviceSettings: {}, | |
stylesheetTemplate: '' | |
}; | |
/** | |
* Init. | |
* | |
* @param {object} args - Args. | |
* @param {Array} args.deviceSettings - List of settings IDs to preview. | |
* @param {string} args.stylesheetTemplate - Stylesheet template. | |
* @returns {void} | |
*/ | |
component.init = function( args ) { | |
component.style = $( '#wpse-286268' ); | |
component.stylesheetTemplate = args.stylesheetTemplate; | |
// After all settings are defined, start previewing changes to all of them. | |
api.apply( api, _.values( args.deviceSettings ).concat( function onceSettingsRegistered() { | |
_.each( arguments, function( setting ) { | |
component.deviceSettings[ setting.id ] = setting; | |
setting.bind( component.updatePreview ); | |
} ); | |
} ) ); | |
}; | |
/** | |
* Update preview. | |
* | |
* @returns {void} | |
*/ | |
component.updatePreview = function updatePreview() { | |
var css = component.stylesheetTemplate; | |
_.each( component.deviceSettings, function( setting ) { | |
css = css.replace( '{{' + setting.id + '}}', setting.get() ); | |
} ); | |
component.style.text( css ); | |
}; | |
return component; | |
} )( wp.customize, jQuery ); |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Plugin Name: WPSE 286268 | |
* Description: Demonstration of adding controls which are contextual to device previews. | |
* Plugin URI: https://wordpress.stackexchange.com/q/286268/8521 | |
* Version: 0.1.0 | |
* Author: Weston Ruter, XWP | |
* Author URI: https://weston.ruter.net/ | |
* License: GPLv2+ | |
* | |
* @package WPSE_286268 | |
*/ | |
/** | |
* Class WPSE_286268_Plugin | |
*/ | |
class WPSE_286268_Plugin { | |
/** | |
* Device configs. | |
* | |
* @var array | |
*/ | |
public $device_configs = array(); | |
/** | |
* Stylesheet template. | |
* | |
* @var string | |
*/ | |
public $stylesheet_template; | |
/** | |
* Registered device settings. | |
* | |
* @var array | |
*/ | |
public $registered_settings = array(); | |
/** | |
* Registered device controls. | |
* | |
* @var array | |
*/ | |
public $registered_controls = array(); | |
/** | |
* Init. | |
*/ | |
public function init() { | |
$this->device_configs = array( | |
'desktop' => array( | |
'label' => __( 'Desktop element outline', 'wpse-286268' ), | |
'default' => '#ff0000', | |
), | |
'tablet' => array( | |
'label' => __( 'Tablet element outline', 'wpse-286268' ), | |
'default' => '#00ff00', | |
), | |
'mobile' => array( | |
'label' => __( 'Mobile element outline', 'wpse-286268' ), | |
'default' => '#0000ff', | |
), | |
); | |
$this->stylesheet_template = ' | |
* { | |
outline: solid 1px {{outline_color_desktop}}; | |
} | |
@media screen and ( max-width: 720px ) { | |
* { | |
outline: solid 1px {{outline_color_tablet}}; | |
} | |
} | |
@media screen and ( max-width: 320px ) { | |
* { | |
outline: solid 1px {{outline_color_mobile}}; | |
} | |
} | |
'; | |
add_action( 'customize_register', array( $this, 'customize_register' ), 20 ); | |
add_action( 'customize_controls_enqueue_scripts', array( $this, 'enqueue_controls_scripts' ) ); | |
add_action( 'customize_preview_init', function() { | |
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_preview_scripts' ) ); | |
} ); | |
add_action( 'wp_print_styles', array( $this, 'print_styles' ), 20 ); | |
} | |
/** | |
* Print styles. | |
*/ | |
public function print_styles() { | |
echo '<style id="wpse-286268" type="text/css">'; | |
$css = $this->stylesheet_template; | |
$tpl_vars = array(); | |
foreach ( $this->device_configs as $slug => $params ) { | |
$tpl_vars[ '{{outline_color_' . $slug . '}}' ] = get_theme_mod( "outline_color_{$slug}", $params['default'] ); | |
} | |
echo esc_html( str_replace( | |
array_keys( $tpl_vars ), | |
array_values( $tpl_vars ), | |
$css | |
) ); | |
echo '</style>'; | |
} | |
/** | |
* Customize register. | |
* | |
* @param WP_Customize_Manager $wp_customize Manager. | |
*/ | |
public function customize_register( WP_Customize_Manager $wp_customize ) { | |
$section = $wp_customize->get_section( 'colors' ); | |
if ( ! $section ) { | |
$section = $wp_customize->add_section( 'colors', array( | |
'title' => __( 'Colors', 'wpse-286268' ), | |
) ); | |
} | |
foreach ( array_keys( $wp_customize->get_previewable_devices() ) as $device_slug ) { | |
if ( ! isset( $this->device_configs[ $device_slug ] ) ) { | |
continue; | |
} | |
$setting = $wp_customize->add_setting( "outline_color_{$device_slug}", array( | |
'transport' => 'postMessage', | |
'sanitize_callback' => 'sanitize_hex_color', | |
'default' => $this->device_configs[ $device_slug ]['default'], | |
) ); | |
$this->registered_settings[ $device_slug ] = $setting; | |
$control_arg = array_merge( | |
$this->device_configs[ $device_slug ], | |
array( | |
'settings' => array( $setting->id ), | |
'section' => $section->id, | |
) | |
); | |
$control = new WP_Customize_Color_Control( $wp_customize, "outline_color_{$device_slug}", $control_arg ); | |
$wp_customize->add_control( $control ); | |
$this->registered_controls[ $device_slug ] = $control; | |
} | |
} | |
/** | |
* Enqueue controls scripts. | |
*/ | |
public function enqueue_controls_scripts() { | |
$handle = 'wpse-286268-controls'; | |
wp_enqueue_script( $handle, plugin_dir_url( __FILE__ ) . 'wpse-286268-controls.js', array( 'customize-controls' ) ); | |
$exports = array( | |
'deviceControls' => wp_list_pluck( $this->registered_controls, 'id' ), | |
); | |
wp_add_inline_script( $handle, sprintf( 'wpse286268controls.init( %s );', wp_json_encode( $exports ) ) ); | |
} | |
/** | |
* Enqueue preview scripts. | |
*/ | |
public function enqueue_preview_scripts() { | |
$handle = 'wpse-286268-preview'; | |
wp_enqueue_script( $handle, plugin_dir_url( __FILE__ ) . 'wpse-286268-preview.js', array( 'customize-preview' ), false, true ); | |
$exports = array( | |
'stylesheetTemplate' => $this->stylesheet_template, | |
'deviceSettings' => wp_list_pluck( $this->registered_settings, 'id' ), | |
); | |
wp_add_inline_script( $handle, sprintf( 'wpse286268preview.init( %s );', wp_json_encode( $exports ) ) ); | |
} | |
} | |
if ( version_compare( strtok( get_bloginfo( 'version' ), '-' ), '4.9', '>=' ) ) { | |
$wpse_286268 = new WPSE_286268_Plugin(); | |
$wpse_286268->init(); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Line 135 of the PHP causes an error. Should be changed to: