New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add facility for previewing changes in realtime with postMessage #37

Merged
merged 24 commits into from Dec 14, 2013

Conversation

Projects
None yet
2 participants
@westonruter
Contributor

westonruter commented Dec 7, 2013

Making changes with Widget Customizer currently can be slow, and this is because each change results in a refresh of the preview window to see the change.

Re-ordering widgets should be possible completely with postMessage, as we can just rearrange the .widget elements. Likewise, widgets should be generally be deletable using postMessage. For adding or changing widgets, however, they may enqueue a script or style, or there may be some setup that expects the widget to be initialized once upon page load. So we cannot by default allow new widgets to be added or existing widgets to be changed, while using postMessage as the transport mechanism. However, there should be a facility in place for widgets to inform the customizer for how they can be updated in realtime. The Widget Customizer can come bundled with postMessage handlers for all widgets that come with Core.

If using postMessage, we can also update widgets before having to wait for the user to click the widget's Save button. As such, if a widget has a postMessage handler, then the Save button should be hidden or disabled with the label changed to something like "Auto-saved".

  • Update widgets with postMessage
  • Insert new widgets into the preview when a new widget is added; will require dynamically binding to the newly-created values.
  • Allow widgets to be re-ordered with postMessage.
  • A theme may need to opt-in to postMessage widget updating via add_theme_support()
  • When removing the last widget from a sidebar so that none are left being rendered, must trigger a refresh
  • Allow widgets to be assigned to other sidebars with postMessage (or rather, fix it so it is not broken. A refresh is still needed due to changed sidebar args.)
  • Fire event when widget is updated with postMessage so plugin and theme can reinitialize if needed (e.g. Masonry in TwentyThirteen)
  • Require that widgets opt-in of supporting live previews. Add support for all core widgets.
  • Preview does not refresh when initially adding a widget that does not support live previews. Such a widget currently has to be forcibly updated to then appear. This is a problem for widgets that lack forms.
@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Nov 11, 2013

Contributor

For text widgets (and other widgets too), we'll need to make sure we apply force_balance_tags

Contributor

westonruter commented Nov 11, 2013

For text widgets (and other widgets too), we'll need to make sure we apply force_balance_tags

@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Nov 11, 2013

Contributor

See discussion from today's #widgets-ui chat.

Contributor

westonruter commented Nov 11, 2013

See discussion from today's #widgets-ui chat.

@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Nov 16, 2013

Contributor

Work is underway in the issue-37-postmessage branch.

Contributor

westonruter commented Nov 16, 2013

Work is underway in the issue-37-postmessage branch.

westonruter added some commits Nov 17, 2013

Render widgets on current REQUEST_URI not admin-ajax
The Jetpack Widget Visibility adds filters based on whether is_admin(), so these work now.
Likewise, widgets may show/hide based on whether they are rendered on a certain page,
so this will also work now.
Enable postMessage updates based on opt-in availability
Add 'widget-customizer' theme support feature
Fix addition of newly-added uninitialized widgets in preview
Correct logic for obtaining list of postMessage-eligible widgets

Fixes #61
Add live preview theme support for bundled themes
Especially for twentythirteen which uses Masonry to lay out widgets in a sidebar.

Other themes can hook into wp.customize.bind( 'sidebar-updated', function ( sidebar_id ) { ... } )
@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Dec 8, 2013

Contributor

@shaunandrews: Please try this out! I've added support so that themes can opt-in to supporting live previews of widget changes, and added built-in support for twentythirteen (see d809152). For your own themes, you'll have to add:

add_theme_support( 'widget-customizer' );

And then if widgets get dynamically positioned or some special layout logic gets applied upon page load, then you'll need to enqueue a script in which listens for changes to the sidebars (or widgets) and then re-applies whatever logic is needed. See for example for twentythirteen:

/*global jQuery, wp */
jQuery( function ($) {
    wp.customize.bind( 'sidebar-updated', function ( sidebar_id ) {
        if ( 'sidebar-1' === sidebar_id && $.isFunction( $.fn.masonry ) ) {
            var widget_area = $( '#secondary .widget-area' );
            widget_area.masonry( 'reloadItems' );
            widget_area.masonry();
        }
    } );
} );
Contributor

westonruter commented Dec 8, 2013

@shaunandrews: Please try this out! I've added support so that themes can opt-in to supporting live previews of widget changes, and added built-in support for twentythirteen (see d809152). For your own themes, you'll have to add:

add_theme_support( 'widget-customizer' );

And then if widgets get dynamically positioned or some special layout logic gets applied upon page load, then you'll need to enqueue a script in which listens for changes to the sidebars (or widgets) and then re-applies whatever logic is needed. See for example for twentythirteen:

/*global jQuery, wp */
jQuery( function ($) {
    wp.customize.bind( 'sidebar-updated', function ( sidebar_id ) {
        if ( 'sidebar-1' === sidebar_id && $.isFunction( $.fn.masonry ) ) {
            var widget_area = $( '#secondary .widget-area' );
            widget_area.masonry( 'reloadItems' );
            widget_area.masonry();
        }
    } );
} );
@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Dec 9, 2013

Contributor

For a non-core widget to opt-in to using the postMessage transport, the widget need only hook in to one of these filters:

$live_previewable = apply_filters( 'customizer_widget_live_previewable', $live_previewable, $id_base );
$live_previewable = apply_filters( "customizer_widget_live_previewable_{$id_base}", $live_previewable );

For example:

class Foo_Widget extends WP_Widget {
    function __construct() {
        parent::__construct(
            'foo', // Base ID
            __( 'Foo', 'text_domain' ) // Name
        );
        add_filter( 'customizer_widget_live_previewable_foo', '__return_true' ); // <==== HERE
...
Contributor

westonruter commented Dec 9, 2013

For a non-core widget to opt-in to using the postMessage transport, the widget need only hook in to one of these filters:

$live_previewable = apply_filters( 'customizer_widget_live_previewable', $live_previewable, $id_base );
$live_previewable = apply_filters( "customizer_widget_live_previewable_{$id_base}", $live_previewable );

For example:

class Foo_Widget extends WP_Widget {
    function __construct() {
        parent::__construct(
            'foo', // Base ID
            __( 'Foo', 'text_domain' ) // Name
        );
        add_filter( 'customizer_widget_live_previewable_foo', '__return_true' ); // <==== HERE
...

westonruter added some commits Dec 9, 2013

Fix initial render of newly added widget without live previewability
Fixes:
Preview does not refresh when initially adding a widget that
does not support live previews. Such a widget currently has to be
forcibly updated to then appear. This is a problem for widgets that
lack forms.
@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Dec 12, 2013

Contributor

@shaunandrews here's what it should look like, and a hack to help detect when a refresh is actually happening:

customize__wordpress_develop___just_another_wordpress_site-8

Contributor

westonruter commented Dec 12, 2013

@shaunandrews here's what it should look like, and a hack to help detect when a refresh is actually happening:

customize__wordpress_develop___just_another_wordpress_site-8

@shaunandrews

This comment has been minimized.

Show comment
Hide comment
@shaunandrews

shaunandrews Dec 13, 2013

Contributor

@westonruter Funny thing: I'm not able to type into the search input since it triggers the highlight and loses focus. I get why this happens, and I'm not actually sure if its a problem.

Contributor

shaunandrews commented Dec 13, 2013

@westonruter Funny thing: I'm not able to type into the search input since it triggers the highlight and loses focus. I get why this happens, and I'm not actually sure if its a problem.

@shaunandrews

This comment has been minimized.

Show comment
Hide comment
@shaunandrews

shaunandrews Dec 13, 2013

Contributor

Ah, so this is working, but it wasn't immediately obvious what I was doing wrong. I was adding text to the search input inside the search widget — and then I updated the title of the search widget. This caused the text to go away and made me think things weren't working. I soon realized that the entire search widget was being redrawn, which makes sense. Changing the title of a different widget left the text inside the search widget unchanged. Nice.

Contributor

shaunandrews commented Dec 13, 2013

Ah, so this is working, but it wasn't immediately obvious what I was doing wrong. I was adding text to the search input inside the search widget — and then I updated the title of the search widget. This caused the text to go away and made me think things weren't working. I soon realized that the entire search widget was being redrawn, which makes sense. Changing the title of a different widget left the text inside the search widget unchanged. Nice.

westonruter added a commit that referenced this pull request Dec 14, 2013

Merge pull request #37 from x-team/issue-37-postmessage
Add facility for previewing changes in realtime with postMessage

@westonruter westonruter merged commit 83dfb43 into develop Dec 14, 2013

1 check passed

default The Travis CI build passed
Details
@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Dec 15, 2013

Contributor

@shaunandrews I fleshed out a full example for how to add support to Widget Customizer for sidebars and widgets which have JavaScript initialization: https://gist.github.com/westonruter/7965203

Contributor

westonruter commented Dec 15, 2013

@shaunandrews I fleshed out a full example for how to add support to Widget Customizer for sidebars and widgets which have JavaScript initialization: https://gist.github.com/westonruter/7965203

@westonruter

This comment has been minimized.

Show comment
Hide comment
@westonruter

westonruter Dec 15, 2013

Contributor

@shaunandrews also, in v0.10.1 I made it so that you have to shift+click in order to open a widget control in the customizer panel. So now you'll be able to better interact with widgets without that annoyance you experienced.

Contributor

westonruter commented Dec 15, 2013

@shaunandrews also, in v0.10.1 I made it so that you have to shift+click in order to open a widget control in the customizer panel. So now you'll be able to better interact with widgets without that annoyance you experienced.

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