Skip to content

Instantly share code, notes, and snippets.

@aristath
Last active July 24, 2019 21:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aristath/5f354e6f37332d140f835e368c07d9b2 to your computer and use it in GitHub Desktop.
Save aristath/5f354e6f37332d140f835e368c07d9b2 to your computer and use it in GitHub Desktop.
<?php
/**
* Plugin Name: parent-theme-mods-loader
*/
add_action(
'customize_register',
/**
* Hooks in customize_register to load our control, register settings and do what needs to be done.
*
* @param WP_Customize_Manager $wp_customize The WordPress Customizer object.
* @return void
*/
function( $wp_customize ) {
/**
* A custom control.
* Contains a simple button to allow loading a set of options.
*
* TODO: This class should be on a separate file.
*/
class WPTRT_Parent_Theme_Mods_Loader_Button extends \WP_Customize_Control {
/**
* The control type.
*
* @access public
* @var string
*/
public $type = 'wptrt-load-settings-buttons';
/**
* An array of options that will be passed-on to the JS.
*
* @access public
* @var array
*/
public $choices;
/**
* Enqueue scripts.
*
* @access public
* @return void
*/
public function enqueue() {
// TODO: Enqueue script (currently added via an anonymous function in customize_controls_print_footer_scripts).
}
/**
* Pass variables to our JS template.
*
* @access public
* @return void
*/
public function to_json() {
parent::to_json();
$this->json['choices'] = $this->choices;
}
/**
* JS template for the control.
*
* @access public
* @return void
*/
protected function content_template() {
?>
<label>
<span class="customize-control-title">{{{ data.label }}}</span>
<# if ( data.description ) { #>
<span class="description customize-control-description">{{{ data.description }}}</span>
<# } #>
</label>
<button class="button">{{ data.choices.button_text }}</button>
<?php
}
}
// Register control-type. Whitelists the control for JS templating.
$wp_customize->register_control_type( 'WPTRT_Parent_Theme_Mods_Loader_Button' );
// Get theme details.
$theme = wp_get_theme();
// Get the template name (parent theme).
$template = $theme->get( 'Template' );
// If we found a parent theme, add control.
if ( $template ) {
// Add control.
$wp_customize->add_control(
new \WPTRT_Parent_Theme_Mods_Loader_Button(
$wp_customize,
'wptrt_load_parent_theme_mods',
[
'section' => 'title_tagline',
'settings' => [],
'priority' => 999,
'choices' => [
'setting' => 'theme_mods_' . $template,
'button_text' => esc_html__( 'Load parent theme settings' ),
],
]
)
);
}
}
);
add_action(
'customize_controls_print_footer_scripts',
/**
* Add footer scripts.
*
* @return void
*/
function() {
/**
* TODO: This should be on a separate file that gets enqueued
* in the WPTRT_Parent_Theme_Mods_Loader_Button::enqueue() method.
*/
?>
<script>
wp.customize.controlConstructor['wptrt-load-settings-buttons'] = wp.customize.Control.extend( {
/**
* Runs when the control is ready.
*/
ready: function() {
var control = this,
button = control.container.find( 'button' );
// When we click on the button trigger the loadSettings method.
button.on( 'click', function( event ) {
event.preventDefault();
control.loadSettings();
});
},
/**
* Load settings and replace existing values in controls.
*/
loadSettings: function() {
// Data for the AJAX request.
let data = {
action: 'wptrt_load_parent_theme_mods',
nonce: '<?php echo esc_html( wp_create_nonce( 'wptrt_load_parent_theme_mods' ) ); ?>',
setting: this.params.choices.setting
};
// Make the call.
jQuery.post( ajaxurl, data, function( response ) {
let settings = [];
// Try to decode the response.
try {
settings = JSON.parse( response );
} catch (error) {
// Nothing to do.
}
// Make sure the response is an object now.
if ( _.isObject( settings ) ) {
// Loop settings.
_.each( settings, function( val, key ) {
// Find the control.
let control = wp.customize.control( key );
// If the control exists, change its value.
if ( control ) {
control.setting.set( val );
}
} );
}
} );
}
} );
</script>
<?php
},
999
);
add_action(
'wp_ajax_wptrt_load_parent_theme_mods',
/**
* AJAX Callback.
*/
function() {
// Security: Check if the nonce is valid.
check_ajax_referer( 'wptrt_load_parent_theme_mods', 'nonce' );
// Sanity check: Make sure we've got everything we need.
if ( isset( $_POST['action'] ) && 'wptrt_load_parent_theme_mods' === $_POST['action'] && isset( $_POST['setting'] ) ) {
// Get the setting-name.
$setting = sanitize_text_field( wp_unslash( $_POST['setting'] ) );
// Print the option value.
echo wp_json_encode( get_option( $setting, [] ) );
}
wp_die();
}
);
@joyously
Copy link

I had a thought.
theme_mods is a sparse array. I wonder if it would be desired to fill the holes with the parent theme's default values. Doing that is a little trickier.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment