Last active

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Demonstrate how to add support to Widget Customizer for sidebars and widgets which have JavaScript initialization http://wordpress.org/plugins/widget-customizer/

View functions.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
<?php
/**
* The functions.php for a theme, adding theme support for widget-customizer,
* and registering a sidebar whose widgets maintain equal heights even when
* widgets in the sidebar are updated via Customizer. This is for demonstration
* purposes, and normally JS wouldn't be embedded in PHP.
* @see http://wordpress.org/plugins/widget-customizer/
*/
/**
* Without this, all changes to sidebars and widgets in the customizer cause a
* full refresh of the preview. By opting-in to widget-customizer support, the
* Widget Customizer plugin then knows that the theme is prepared for updating
* the sidebars and widgets via the postMessage transport, dynamically updating
* the elements via the DOM and not doing a full refresh.
*/
add_theme_support( 'widget-customizer' );
/**
* Register a new sidebar which has dynamic layout
*/
register_sidebar( array(
'name' => __( 'Equal Heights' ),
'id' => 'equal-heights',
) );
/**
* Note: This is not necessary because the 'widget-customizer' theme support by
* default makes all sidebars live-previewable; if you need to prevent an entire
* sidebar from being live-previewed (i.e. postMessage update transport), then
* you can have this filter __return_false
*/
// add_filter( 'customizer_sidebar_widgets_live_previewable_masonry-layout', '__return_true' );
/**
* Render a sidebar in the footer which we'll use to contain widgets that get
* equal heights applied to them at initialization.
*/
add_action( 'wp_footer', function () {
?>
<?php if ( is_active_sidebar( 'equal-heights' ) ): ?>
<div id="equal-heights" class="sidebar">
<?php dynamic_sidebar( 'equal-heights' ); ?>
</div>
<?php endif; ?>
<?php
} );
/**
* Inject the JavaScript which runs the equal-heights logic on the sidebar,
* and which will re-equalize the sidebar when it is updated.
*/
add_action( 'wp_footer', function () {
wp_print_scripts( array( 'jquery' ) );
?>
<script>
jQuery( function ( $ ) {
/**
* Courtesy of http://jsfiddle.net/xBZjG/23/
*/
$.fn.equalHeights = function(base_height) {
var itemsbatch = this;
if (base_height === 0) {
base_height = Math.max.apply(null, this.map(function() {
return $(this).height();
}).get());
}
itemsbatch.height(base_height);
itemsbatch.each(function() {
var elemToResize = this;
$(elemToResize).find('img').load(function() {
if (elemToResize.height > base_height) {
itemsbatch.equalHeights(elemToResize.height);
}
});
});
return base_height;
};
/**
* Set up the button to be able to open the lightbox. This is just
* for a simple example for demonstration purposes. A smarter
* widget would rely on event delegation to not have to re-bind the
* event handlers whenever the widget is updated.
* @param widget_el
*/
var initialize_sidebar = function () {
$( '#equal-heights > .widget' ).equalHeights( 0 );
};
// Invoke now at DOM ready
initialize_sidebar();
/**
* Now, if we're also in the customizer preview, add support for
* Widget Customizer to re-initialize sidebar when it is updated.
*/
if ( typeof wp !== 'undefined' && typeof wp.customize !== 'undefined' ) {
wp.customize.bind( 'sidebar-updated', function ( sidebar_id ) {
if ( 'equal-heights' === sidebar_id ) {
initialize_sidebar();
}
} );
}
} );
</script>
<?php
} );
View functions.php
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
<?php
/**
* Plugin Name: Lightbox Widget
* Description: Demonstrate how to add live-previewability to Widget Customizer for JS-powered widgets
* Author: Weston Ruter, X-Team
* Author URI: http://x-team.com/profile/weston-ruter/
*/
class Lightbox_Widget extends WP_Widget {
function __construct() {
parent::__construct(
'lightbox',
__( 'Lightbox', 'lightbox-widget' ),
array(
'description' => __( 'Displays a button which opens a lightbox to show the supplied content.', 'lightbox-widget' ),
/**
* Opt-in widget for Widget Customizer live previews via postMessage
* transport. This indicates that live previews are supported.
*/
'customizer_support' => true,
)
);
add_action( 'wp_enqueue_scripts', function () {
wp_enqueue_script( 'colorbox', '//cdnjs.cloudflare.com/ajax/libs/jquery.colorbox/1.4.3/jquery.colorbox-min.js', array( 'jquery' ), false );
wp_enqueue_style( 'colorbox', '//cdnjs.cloudflare.com/ajax/libs/jquery.colorbox/1.4.3/example1/colorbox.css', array(), false );
} );
/**
* Alternative method to the customizer_support widget option above to
* opt-in to customizer support.
*/
// add_filter( 'customizer_widget_live_previewable_lightbox', '__return_true' );
/**
* Prepare to add support for the widget to be live-previewable
*/
add_action( 'wp_footer', array( $this, 'add_widget_behaviors' ) );
}
/**
* Inject the JavaScript for initializing the widget and re-initializing it
* when the widget is updated. Here the JS is rendered out to the page, but
* normally should be enqueued in a separate file.
* @action wp_footer
*/
public function add_widget_behaviors() {
wp_print_scripts( array( 'jquery' ) )
?>
<script>
jQuery( function ( $ ) {
/**
* Set up the button to be able to open the lightbox. This is just
* for a simple example for demonstration purposes. A smarter
* widget would rely on event delegation to not have to re-bind the
* event handlers whenever the widget is updated.
* @param widget_el
*/
var initialize_widget = function ( widget_el ) {
$( widget_el ).find( 'button' ).click( function (e) {
e.stopPropagation();
$.colorbox( {
html: $( this ).data( 'content' ),
width: '50%'
} );
} );
};
/**
* Initialize widgets upon DOM ready
*/
$( '.widget_lightbox' ).each( function () {
initialize_widget( this );
} );
/**
* Now, if we're also in the customizer preview, add support for
* Widget Customizer to re-initialize widget when it is updated.
*/
if ( typeof wp !== 'undefined' && typeof wp.customize !== 'undefined' ) {
wp.customize.bind( 'widget-updated', function ( widget_id ) {
// We only care about the lightbox widget being updated here
if ( ! /^lightbox-\d+/.test( widget_id ) ) {
return;
}
// Re-initialize the widget
var widget_el = $( '#' + widget_id );
initialize_widget( widget_el );
// Update the lightbox content if the lightbox is currently shown
if ( $( '#colorbox' ).is( ':visible' ) ) {
widget_el.find( 'button' ).click();
}
} );
}
} );
</script>
<?php
}
/**
* Convenience method so we don't have to check isset() to prevent array index not defined notices
* @param array $instance
* @return array
*/
public function instance_with_defaults( array $instance ) {
return array_merge(
array(
'title' => __( 'Lightbox Widget', 'lightbox-widget' ),
'content' => __( '(Empty)', 'lightbox-widget' ),
),
array_filter( $instance )
);
}
/**
* @param array $instance
* @return void
*/
public function form( $instance ) {
$instance = $this->instance_with_defaults( $instance );
?>
<p>
<label for="<?php echo $this->get_field_id( 'title' ); ?>"><?php esc_html_e( 'Title:', 'lightbox-widget' ) ?></label>
<input id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" value="<?php echo esc_attr( $instance["title"] ) ?>">
</p>
<p>
<label for="<?php echo $this->get_field_id( 'content' ); ?>"><?php esc_html_e( 'Content:', 'lightbox-widget' ) ?></label><br>
<textarea id="<?php echo $this->get_field_id( 'content' ); ?>" name="<?php echo $this->get_field_name( 'content' ); ?>"><?php echo esc_textarea( $instance["content"] ) ?></textarea>
</p>
<?php
}
/**
* @param array $args
* @param array $instance
*/
public function widget( $args, $instance ) {
$instance = $this->instance_with_defaults( $instance );
extract( $args );
echo $before_widget;
echo $before_title;
echo apply_filters( 'widget_title', $instance['title'] );
echo $after_title;
$content = apply_filters( 'the_content', $instance['content'] );
?>
<p>
<button type="button" type="button" data-content="<?php echo esc_attr( $content ) ?>"><?php esc_html_e( 'Open Lightbox', 'lightbox-widget' ) ?></button>
</p>
<?php
echo $after_widget;
}
}
add_action( 'widgets_init', function () {
register_widget( 'Lightbox_Widget' );
} );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.