Summary: Learning about the WordPress custom Widgets and Customizer JavaScript API for better user experience.
Widgets
WordPress widgets allow users to add content and features to sidebars and other widget-ready areas on their website. By default, WordPress includes several built-in widgets such as Recent Posts, Categories, Search, etc. We can create custom widgets to enhance our site with unique functionalities tailored to our specific needs.
__construct()
: Initialize the widget like naming the widget and setting description.widget()
: Outputs the front-end display of the widget.form()
: Outputs the form for the widget settings in the WordPress admin.update()
: Processes and saves the widget options when a user updates them.
class My_Custom_Widget extends WP_Widget {
// Step 1: Constructor
function __construct() {
parent::__construct(
'my_custom_widget',
__('My Custom Widget', 'text_domain'),
array('description' => __('A Custom Widget', 'text_domain'))
);
}
// Step 2: Front-End Display
public function widget($args, $instance) {
echo $args['before_widget'];
if (!empty($instance['title'])) {
echo $args['before_title'] . apply_filters('widget_title', $instance['title']) . $args['after_title'];
}
echo __('Hello, World!', 'text_domain');
echo $args['after_widget'];
}
// Step 3: Back-End Form (for admin panel)
public function form($instance) {
$title = !empty($instance['title']) ? $instance['title'] : __('New title', 'text_domain');
?>
<p>
<label for="<?php echo esc_attr($this->get_field_id('title')); ?>"><?php _e('Title:'); ?></label>
<input class="widefat" id="<?php echo esc_attr($this->get_field_id('title')); ?>" name="<?php echo esc_attr($this->get_field_name('title')); ?>" type="text" value="<?php echo esc_attr($title); ?>">
</p>
<?php
}
// Step 4: Save Widget Settings
public function update($new_instance, $old_instance) {
$instance = array();
$instance['title'] = (!empty($new_instance['title'])) ? strip_tags($new_instance['title']) : '';
return $instance;
}
}
// Step 5: Register the Widget
function register_my_custom_widget() {
register_widget('My_Custom_Widget');
}
add_action('widgets_init', 'register_my_custom_widget');
Customizer JavaScript API
Relating Controls, Sections, and Panels together
<?php
$wp_customize->add_control(
'blogname',
array(
'label' => __( 'Site Title' ),
'section' => 'title_tagline',
)
);
?>
id = wp.customize.control( 'blogname' ).section(); // returns title_tagline by default
wp.customize.control( 'blogname' ).section( 'nav' );
wp.customize.control( 'blogname' ).section( 'nav' );
sections = wp.customize.panel( 'widgets' ).sections();controls = wp.customize.section( 'title_tagline' ).controls();
// Move all controls from one section to another.
_.each( wp.customize.section( 'title_tagline' ).controls(), function ( control ) {
control.section( 'nav' );
} );
Contextual Panels, Sections, and Controls
Control,
Panel,
and Section
instances have an active
state a wp.customize.Value
instance. When the active
state changes, the panel, section, and control instances invoke their respective onChangeActive
method, which by default slides the container element up and down, if false
and true
respectively. There are also activate()
and deactivate()
methods now for manipulating this active
state, for panels, sections, and controls. The primary purpose of these states is to show or hide the object without removing it entirely from the Customizer.
wp.customize.section( 'nav' ).deactivate(); // slide up
wp.customize.section( 'nav' ).activate({ duration: 1000 }); // slide down slowly
wp.customize.section( 'colors' ).deactivate({ duration: 0 }); // hide immediately
wp.customize.section( 'nav' ).deactivate({ completeCallback:
function () {
wp.customize.section( 'colors' ).activate(); // show after nav hides completely
} } );
Focusing UI Objects
Building upon the expand()
/collapse()
methods for panels, sections, and controls, these models also support a focus()
method which not only expands all of the necessary elements, but also scrolls the target container into view and puts the browser focus on the first focusable element in the container. For instance, to expand the “Static Front Page” section and focus on select dropdown for the “Front page”.
wp.customize.control( 'page_on_front' ).focus()
Priorities
When registering a panel, section, or control in PHP, we can supply a priority
parameter. This value is stored in a wp.customize.Value
instance for each respective Panel
, Section
, and Control
instance
priority = wp.customize.panel( 'widgets' ).priority(); // returns 110 by default
wp.customize.panel( 'widgets' ).priority( 1 ); // move Widgets to the top
Selective Refresh
Selective Refresh updates in the Customizer “preview” only refresh areas whose associate settings are changed. By only updating the elements that have changed, it’s much faster and less disruptive than a full-iframe refresh.
The logic in pure-JavaScript postMessage
updates is duplicated. The JavaScript in the Customizer must mirror the PHP that produces the markup, or take shortcuts to approximate it. But Selective Refresh is DRY as there’s no duplication of JavaScript and PHP. An Ajax request retrieves the new markup for the preview.
Registering Partials
Setting previews need to opt-in to use Selective Refresh by registering the necessary partials. Selective Refresh is added for the blogdescription
setting by adding a partial with the same name.
function foo_theme_customize_register( WP_Customize_Manager $wp_customize ) {
$wp_customize->selective_refresh->add_partial( 'blogdescription', array(
'selector' => '.site-description',
'container_inclusive' => false,
'render_callback' => function() {
bloginfo( 'description' );
},
) );
}
add_action( 'customize_register', 'foo_theme_customize_register' );
Selective Refresh JavaScript Events
partial-content-rendered
: When the placement is rendered. JavaScript-driven widgets can re-build on this event.render-partials-response
: When data is returned, after a request for partial rendering. The server filters this data with ‘customize_render_partials_response’.partial-content-moved
: When a widget has moved in its sidebar. As shown above, JavaScript-driven widgets can refresh on this event.widget-updated
: When theWidgetPartial
is refreshed with itsrenderContent
method.sidebar-updated
: When a sidebar has a widget that’s refreshed or updated. Or when a sidebar’s widgets are sorted, usingreflowWidgets()
.
Support for selective refresh in widget
add_theme_support( 'customize-selective-refresh-widgets' );
class Foo_Widget extends WP_Widget {
public function __construct() {
parent::__construct(
‘foo’,
__( 'Example', 'bar-plugin' ),
array(
'description' => __( ‘An example widget’, ‘bar-plugin’ ),
'customize_selective_refresh' => true,
)
);
if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
}
}
}
Leave a Reply