Skip to content

Commit

Permalink
[edit-widgets beta] Preload widgets (WordPress#24855)
Browse files Browse the repository at this point in the history
* First stab at preloading widgets

* Use a pre-rendered widget form when the page is first loaded (instead of starting with XHR for each widget)

* Adjust tests

* Lint

* Lint
  • Loading branch information
adamziel authored Aug 27, 2020
1 parent 44e1bfa commit b63cfef
Show file tree
Hide file tree
Showing 6 changed files with 109 additions and 24 deletions.
52 changes: 35 additions & 17 deletions lib/class-wp-rest-sidebars-controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,20 +279,23 @@ public static function get_sidebar( $id ) {
/**
* Returns a list of widgets for the given sidebar id
*
* @param string $sidebar_id ID of the sidebar.
* @param string $sidebar_id ID of the sidebar.
* @param WP_REST_Request $request Request object.
*
* @return array
* @global array $wp_registered_widgets
* @global array $wp_registered_sidebars
*/
public static function get_widgets( $sidebar_id ) {
global $wp_registered_widgets, $wp_registered_sidebars;
public static function get_widgets( $sidebar_id, $request ) {
global $wp_registered_widgets, $wp_registered_sidebars, $wp_registered_widget_controls;

$widgets = array();
$sidebars_widgets = (array) wp_get_sidebars_widgets();
$registered_sidebar = isset( $wp_registered_sidebars[ $sidebar_id ] ) ? $wp_registered_sidebars[ $sidebar_id ] : (
$registered_sidebar = isset( $wp_registered_sidebars[ $sidebar_id ] )
? $wp_registered_sidebars[ $sidebar_id ]
: (
'wp_inactive_widgets' === $sidebar_id ? array() : null
);
);

if ( null !== $registered_sidebar && isset( $sidebars_widgets[ $sidebar_id ] ) ) {
foreach ( $sidebars_widgets[ $sidebar_id ] as $widget_id ) {
Expand Down Expand Up @@ -334,9 +337,7 @@ public static function get_widgets( $sidebar_id ) {
}

ob_start();

call_user_func_array( $widget['callback'], $widget_parameters );

$widget['rendered'] = trim( ob_get_clean() );
}

Expand All @@ -351,6 +352,17 @@ public static function get_widgets( $sidebar_id ) {
$widget['id_base'] = $instance->id_base;
}

if ( 'edit' === $request['context'] && isset( $wp_registered_widget_controls[ $widget_id ]['callback'] ) ) {
$control = $wp_registered_widget_controls[ $widget_id ];
$arguments = array();
if ( ! empty( $widget['number'] ) ) {
$arguments[0] = array( 'number' => $widget['number'] );
}
ob_start();
call_user_func_array( $control['callback'], $arguments );
$widget['rendered_form'] = trim( ob_get_clean() );
}

unset( $widget['params'] );
unset( $widget['callback'] );

Expand Down Expand Up @@ -392,7 +404,7 @@ public function prepare_item_for_response( $raw_sidebar, $request ) {

$fields = $this->get_fields_for_response( $request );
if ( rest_is_field_included( 'widgets', $fields ) ) {
$sidebar['widgets'] = self::get_widgets( $sidebar['id'] );
$sidebar['widgets'] = self::get_widgets( $sidebar['id'], $request );
}

$schema = $this->get_item_schema();
Expand Down Expand Up @@ -484,43 +496,49 @@ public function get_item_schema() {
'items' => array(
'type' => 'object',
'properties' => array(
'id' => array(
'id' => array(
'description' => __( 'Unique identifier for the widget.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
),
'id_base' => array(
'id_base' => array(
'description' => __( 'Type of widget for the object.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
),
'widget_class' => array(
'widget_class' => array(
'description' => __( 'Class name of the widget implementation.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
),
'name' => array(
'name' => array(
'description' => __( 'Name of the widget.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
),
'description' => array(
'description' => array(
'description' => __( 'Description of the widget.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
),
'number' => array(
'number' => array(
'description' => __( 'Number of the widget.', 'gutenberg' ),
'type' => 'integer',
'context' => array( 'view', 'edit', 'embed' ),
),
'rendered' => array(
'rendered' => array(
'description' => __( 'HTML representation of the widget.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'view', 'edit', 'embed' ),
'context' => array( 'view', 'embed' ),
'readonly' => true,
),
'rendered_form' => array(
'description' => __( 'HTML representation of the widget admin form.', 'gutenberg' ),
'type' => 'string',
'context' => array( 'edit' ),
'readonly' => true,
),
'settings' => array(
'settings' => array(
'description' => __( 'Settings of the widget.', 'gutenberg' ),
'type' => 'object',
'context' => array( 'view', 'edit', 'embed' ),
Expand Down
12 changes: 7 additions & 5 deletions packages/block-library/src/legacy-widget/edit/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ import LegacyWidgetEditDomManager from './dom-manager';
const { XMLHttpRequest, FormData } = window;

class LegacyWidgetEditHandler extends Component {
constructor() {
constructor( props ) {
super( ...arguments );
this.state = {
form: null,
form: props.prerenderedEditForm,
};
this.widgetNonce = null;
this.instanceUpdating = null;
Expand All @@ -32,9 +32,11 @@ class LegacyWidgetEditHandler extends Component {
componentDidMount() {
this.isStillMounted = true;
this.trySetNonce();
this.requestWidgetForm( undefined, ( response ) => {
this.props.onInstanceChange( null, !! response.form );
} );
if ( ! this.props.prerenderedEditForm ) {
this.requestWidgetForm( undefined, ( response ) => {
this.props.onInstanceChange( null, !! response.form );
} );
}
}

componentDidUpdate( prevProps ) {
Expand Down
4 changes: 4 additions & 0 deletions packages/block-library/src/legacy-widget/edit/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class LegacyWidgetEdit extends Component {
availableLegacyWidgets,
hasPermissionsToManageWidgets,
isSelected,
prerenderedEditForm,
setAttributes,
widgetId,
} = this.props;
Expand Down Expand Up @@ -127,6 +128,7 @@ class LegacyWidgetEdit extends Component {
id={ widgetId }
idBase={ attributes.idBase || widgetId }
number={ attributes.number }
prerenderedEditForm={ prerenderedEditForm }
widgetName={ get( widgetObject, [ 'name' ] ) }
widgetClass={ attributes.widgetClass }
instance={ attributes.instance }
Expand Down Expand Up @@ -185,6 +187,7 @@ export default withSelect( ( select, { clientId } ) => {
const widgetId = select( 'core/edit-widgets' ).getWidgetIdForClientId(
clientId
);
const widget = select( 'core/edit-widgets' ).getWidget( widgetId );
const editorSettings = select( 'core/block-editor' ).getSettings();
const {
availableLegacyWidgets,
Expand All @@ -194,5 +197,6 @@ export default withSelect( ( select, { clientId } ) => {
hasPermissionsToManageWidgets,
availableLegacyWidgets,
widgetId,
prerenderedEditForm: widget.rendered_form,
};
} )( LegacyWidgetEdit );
7 changes: 7 additions & 0 deletions packages/edit-widgets/src/store/selectors.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,13 @@ export const getWidgets = createRegistrySelector( ( select ) => () => {
);
} );

export const getWidget = createRegistrySelector(
( select ) => ( state, id ) => {
const widgets = select( 'core/edit-widgets' ).getWidgets();
return widgets[ id ];
}
);

export const getWidgetAreas = createRegistrySelector( ( select ) => () => {
if ( ! hasResolvedWidgetAreas( query ) ) {
return null;
Expand Down
1 change: 0 additions & 1 deletion packages/edit-widgets/src/store/transformers.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ export function transformWidgetToBlock( widget ) {
return createBlock(
'core/legacy-widget',
{
rendered: widget.rendered,
form: widget.form,
widgetClass: widget.widget_class,
instance: widget.settings,
Expand Down
57 changes: 56 additions & 1 deletion phpunit/class-rest-sidebars-controller-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,60 @@ public function test_get_items_active_sidebar_with_widgets() {
);
}

/**
*
*/
public function test_get_items_active_sidebar_with_widgets_edit_context() {
$this->setup_widget(
'widget_text',
1,
array(
'text' => 'Custom text test',
)
);
$this->setup_sidebar(
'sidebar-1',
array(
'name' => 'Test sidebar',
),
array( 'text-1' )
);

$request = new WP_REST_Request( 'GET', '/__experimental/sidebars' );
$request['context'] = 'edit';
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertEquals(
array(
array(
'id' => 'sidebar-1',
'name' => 'Test sidebar',
'description' => '',
'status' => 'active',
'widgets' => array(
array(
'id' => 'text-1',
'settings' => array(
'text' => 'Custom text test',
),
'id_base' => 'text',
'widget_class' => 'WP_Widget_Text',
'name' => 'Text',
'description' => 'Arbitrary text.',
'number' => 1,
'rendered' => '<div class="textwidget">Custom text test</div>',
'rendered_form' => '<input id="widget-text-1-title" name="widget-text[1][title]" class="title sync-input" type="hidden" value="">' . "\n" .
' <textarea id="widget-text-1-text" name="widget-text[1][text]" class="text sync-input" hidden>Custom text test</textarea>' . "\n" .
' <input id="widget-text-1-filter" name="widget-text[1][filter]" class="filter sync-input" type="hidden" value="on">' . "\n" .
' <input id="widget-text-1-visual" name="widget-text[1][visual]" class="visual sync-input" type="hidden" value="on">',
),
),
),
),
$data
);
}

/**
*
*/
Expand Down Expand Up @@ -581,7 +635,8 @@ public function test_get_items_inactive_widgets() {
)
);

$request = new WP_REST_Request( 'GET', '/__experimental/sidebars' );
$request = new WP_REST_Request( 'GET', '/__experimental/sidebars' );
$request->set_param( 'context', 'view' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$this->assertEquals(
Expand Down

0 comments on commit b63cfef

Please sign in to comment.