Skip to content

Instantly share code, notes, and snippets.

@jegbagus
Last active March 20, 2018 14:10
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 jegbagus/e6bfe04fe45f4fa91b1fdc1c3b5b7a89 to your computer and use it in GitHub Desktop.
Save jegbagus/e6bfe04fe45f4fa91b1fdc1c3b5b7a89 to your computer and use it in GitHub Desktop.
lazy load control
<?php
/**
* Plugin Name: Lazy Load Control
* Description: Lazy loaded (ajax load) customizer control
* Version: 1.0.0
* Author: Agung Bayu
* Author URI: https://agungbayuiswara.com/
* Text Domain: lazy-load-control
*/
add_action('wp_ajax_call_section_caller', 'jeg_call_section_control');
function jeg_call_section_control()
{
$result = array();
if(isset($_POST['lazy_section']))
{
if($_POST['lazy_section'] === 'dynamic_section')
{
$controlName = 'testDynamicControl';
$result[$controlName] = array(
'setting' => array(
'value' => get_theme_mod($controlName, '#000'),
'transport' => "postMessage",
'type' => 'theme_mod',
),
'control' => array(
'type' => 'color',
'label' => 'Dynamic Control',
'description' => 'Control loaded dynamically',
),
);
}
}
wp_send_json_success( $result );
}
/**
* Register Section Type
*/
add_action( 'customize_register', 'jeg_register_section_type_lazy' );
function jeg_register_section_type_lazy( WP_Customize_Manager $wp_customize )
{
/*****
* Lazy section
*/
class LazySection extends WP_Customize_Section
{
const TYPE = 'lazy';
/**
* Type of control, used by JS.
*
* @access public
* @var string
*/
public $type = self::TYPE;
public $section_caller;
/**
* Constructor.
*
* Any supplied $args override class property defaults.
*
* @throws Exception If there are bad arguments.
*
* @param WP_Customize_Manager $manager Customizer bootstrap instance.
* @param string $id An specific ID for the panel.
* @param array $args Panel arguments.
*/
public function __construct( WP_Customize_Manager $manager, $id, array $args ) {
parent::__construct( $manager, $id, $args );
}
/**
* Render the panel's JS templates.
*
* This function is only run for panel types that have been registered with
* WP_Customize_Manager::register_panel_type().
*
* @see WP_Customize_Manager::register_panel_type()
*/
public function print_template() {
?>
<script type="text/html" id="tmpl-customize-lazy-section-loading">
<li class="customize-lazy-section-loading">
<h3>{{ data.loading }}</h3>
</li>
</script>
<?php
parent::print_template();
}
/**
* Export data to JS.
*
* @return array
*/
public function json() {
$data = parent::json();
$data['section_caller'] = $this->section_caller;
return $data;
}
}
$wp_customize->register_section_type('LazySection');
$section = new LazySection($wp_customize, 'lazy_section', array(
'section_caller' => 'dynamic_section',
'title' => __( 'Lazy Section' ),
'panel' => '',
'priority' => 160,
));
$wp_customize->add_section( $section );
}
add_filter( 'customize_dynamic_setting_args', 'jeg_filter_dynamic_setting_args', 10, 2);
function jeg_filter_dynamic_setting_args($setting_args, $setting_id)
{
if($setting_id === 'testDynamicControl')
{
$setting_args = array(
'type' => 'theme_mod',
);
}
return $setting_args;
}
add_action( 'customize_controls_enqueue_scripts', 'jeg_customizer_control');
function jeg_customizer_control() {
wp_enqueue_script( 'jeg-lazy-load-control', 'lazy-load-control.js', null, null, true );
ob_start();
?>
<script>
/** Section Constructor **/
(function(api){
api.sectionConstructor['lazy'] = api.Section.extend({
loaded : false,
loadingContainer: null,
ready: function() {
var section = this;
api.Section.prototype.ready.call( section );
section.deferred.embedded.done(function() {
section.setupSectionActions();
});
},
setupSectionActions: function(){
var section = this, sectionLoadingTemplate, descriptionContainer;
sectionLoadingTemplate = wp.template( 'customize-lazy-section-loading' );
section.loadingContainer = $(sectionLoadingTemplate({
loading: 'Loading Control'
}));
descriptionContainer = section.container.find( '.section-meta:first' );
descriptionContainer.after( section.loadingContainer );
},
/**
* Allow an active panel to be contextually active even when it has no active controls.
*
* @returns {boolean} Whether contextually active.
*/
isContextuallyActive: function() {
var section = this;
return section.active();
},
load_control : function () {
var section = this;
return wp.ajax.post( 'call_section_caller', {
lazy_section: section.params.section_caller
} );
},
add_control : function (response) {
var section = this;
Object.keys(response).forEach(function(name) {
var item = response[name];
var setting = new api.Setting(name, item.setting.value, {
transport: item.setting.transport,
previewer: api.previewer,
type: item.setting.type,
dirty: false
});
api.add( name, setting );
console.log('[customizer] create setting with name : ' + name);
var control = new api.controlConstructor[item.control.type]( name, {
params: {
section: section.id,
active:true, // need to be calculated
label: item.control.label,
description: item.control.description,
settings: {
'default': name
}
}
} );
api.control.add( control.id, control );
// send to previewer
api.previewer.send('setting-added', JSON.stringify({id: control.id}));
});
section.loaded = true;
section.loadingContainer.slideUp();
},
/**
* handle expand
*
* @param params
* @returns {*|Boolean}
*/
expand : function(params) {
var section = this;
if(!section.loaded)
{
var control = section.load_control();
control.done(section.add_control.bind(this));
}
return this._toggleExpanded( true, params );
}
});
})(wp.customize)
</script>
<?php
$js = str_replace( array( '<script>', '</script>' ), '', trim( ob_get_clean() ) );
wp_add_inline_script( 'jeg-lazy-load-control', $js );
}
add_action( 'customize_preview_init', function(){
add_action( 'wp_enqueue_scripts' , 'jeg_previewer_script');
}, 99 );
function jeg_previewer_script() {
wp_enqueue_script( 'jeg-preview-script', 'preview-script.js', null, null, true );
ob_start();
?>
<script>
(function(api){
api.bind( 'preview-ready', function()
{
api.preview.bind( 'setting-added', function( obj )
{
obj = JSON.parse(obj);
var setting = api(obj.id);
if(setting) {
console.log('[previewer] receive on previewer id : ' + obj.id);
} else {
console.log('[previewer] unable to receive api setting with id : ' + obj.id);
}
} );
} );
})(wp.customize)
</script>
<?php
$js = str_replace( array( '<script>', '</script>' ), '', trim( ob_get_clean() ) );
wp_add_inline_script( 'jeg-preview-script', $js );
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment