Skip to content

Commit

Permalink
Add block editor to customize.php
Browse files Browse the repository at this point in the history
  • Loading branch information
noisysocks committed May 25, 2021
1 parent 5a6c23f commit 2c74335
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 66 deletions.
16 changes: 1 addition & 15 deletions src/wp-admin/widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,21 +23,7 @@
$title = __( 'Widgets' );
$parent_file = 'themes.php';

/**
* Filters whether or not to use the block editor to manage widgets.
*
* @since 5.8.0
*
* @param boolean $use_widgets_block_editor Whether or not to use the block editor to manage widgets.
*/
$use_widgets_block_editor = apply_filters(
'use_widgets_block_editor',
get_theme_support( 'widgets-block-editor' )
);

$use_widgets_block_editor = true;

if ( $use_widgets_block_editor ) {
if ( wp_use_widgets_block_editor() ) {
require ABSPATH . 'wp-admin/widgets-form-blocks.php';
} else {
require ABSPATH . 'wp-admin/widgets-form.php';
Expand Down
5 changes: 5 additions & 0 deletions src/wp-includes/class-wp-customize-control.php
Original file line number Diff line number Diff line change
Expand Up @@ -795,3 +795,8 @@ protected function content_template() {}
* WP_Customize_Date_Time_Control class.
*/
require_once ABSPATH . WPINC . '/customize/class-wp-customize-date-time-control.php';

/**
* WP_Sidebar_Block_Editor_Control class.
*/
require_once ABSPATH . WPINC . '/customize/class-wp-sidebar-block-editor-control.php';
222 changes: 171 additions & 51 deletions src/wp-includes/class-wp-customize-widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,8 @@ public function schedule_customize_register() {
public function customize_register() {
global $wp_registered_widgets, $wp_registered_widget_controls, $wp_registered_sidebars;

$use_widgets_block_editor = wp_use_widgets_block_editor();

add_filter( 'sidebars_widgets', array( $this, 'preview_sidebars_widgets' ), 1 );

$sidebars_widgets = array_merge(
Expand Down Expand Up @@ -446,13 +448,18 @@ public function customize_register() {
if ( $is_active_sidebar ) {

$section_args = array(
'title' => $wp_registered_sidebars[ $sidebar_id ]['name'],
'description' => $wp_registered_sidebars[ $sidebar_id ]['description'],
'priority' => array_search( $sidebar_id, array_keys( $wp_registered_sidebars ), true ),
'panel' => 'widgets',
'sidebar_id' => $sidebar_id,
'title' => $wp_registered_sidebars[ $sidebar_id ]['name'],
'priority' => array_search( $sidebar_id, array_keys( $wp_registered_sidebars ), true ),
'panel' => 'widgets',
'sidebar_id' => $sidebar_id,
);

if ( $use_widgets_block_editor ) {
$section_args['description'] = '';
} else {
$section_args['description'] = $wp_registered_sidebars[ $sidebar_id ]['description'];
}

/**
* Filters Customizer widget section arguments for a given sidebar.
*
Expand All @@ -467,49 +474,63 @@ public function customize_register() {
$section = new WP_Customize_Sidebar_Section( $this->manager, $section_id, $section_args );
$this->manager->add_section( $section );

$control = new WP_Widget_Area_Customize_Control(
$this->manager,
$setting_id,
array(
'section' => $section_id,
'sidebar_id' => $sidebar_id,
'priority' => count( $sidebar_widget_ids ), // place 'Add Widget' and 'Reorder' buttons at end.
)
);
$new_setting_ids[] = $setting_id;
if ( $use_widgets_block_editor ) {
$control = new WP_Sidebar_Block_Editor_Control(
$this->manager,
$setting_id,
array(
'section' => $section_id,
'sidebar_id' => $sidebar_id,
)
);
} else {
$control = new WP_Widget_Area_Customize_Control(
$this->manager,
$setting_id,
array(
'section' => $section_id,
'sidebar_id' => $sidebar_id,
'priority' => count( $sidebar_widget_ids ), // place 'Add Widget' and 'Reorder' buttons at end.
)
);
}

$this->manager->add_control( $control );

$new_setting_ids[] = $setting_id;
}
}

// Add a control for each active widget (located in a sidebar).
foreach ( $sidebar_widget_ids as $i => $widget_id ) {
if ( ! $use_widgets_block_editor ) {
// Add a control for each active widget (located in a sidebar).
foreach ( $sidebar_widget_ids as $i => $widget_id ) {

// Skip widgets that may have gone away due to a plugin being deactivated.
if ( ! $is_active_sidebar || ! isset( $wp_registered_widgets[ $widget_id ] ) ) {
continue;
}
// Skip widgets that may have gone away due to a plugin being deactivated.
if ( ! $is_active_sidebar || ! isset( $wp_registered_widgets[ $widget_id ] ) ) {
continue;
}

$registered_widget = $wp_registered_widgets[ $widget_id ];
$setting_id = $this->get_setting_id( $widget_id );
$id_base = $wp_registered_widget_controls[ $widget_id ]['id_base'];
$registered_widget = $wp_registered_widgets[ $widget_id ];
$setting_id = $this->get_setting_id( $widget_id );
$id_base = $wp_registered_widget_controls[ $widget_id ]['id_base'];

$control = new WP_Widget_Form_Customize_Control(
$this->manager,
$setting_id,
array(
'label' => $registered_widget['name'],
'section' => $section_id,
'sidebar_id' => $sidebar_id,
'widget_id' => $widget_id,
'widget_id_base' => $id_base,
'priority' => $i,
'width' => $wp_registered_widget_controls[ $widget_id ]['width'],
'height' => $wp_registered_widget_controls[ $widget_id ]['height'],
'is_wide' => $this->is_wide_widget( $widget_id ),
)
);
$this->manager->add_control( $control );
$control = new WP_Widget_Form_Customize_Control(
$this->manager,
$setting_id,
array(
'label' => $registered_widget['name'],
'section' => $section_id,
'sidebar_id' => $sidebar_id,
'widget_id' => $widget_id,
'widget_id_base' => $id_base,
'priority' => $i,
'width' => $wp_registered_widget_controls[ $widget_id ]['width'],
'height' => $wp_registered_widget_controls[ $widget_id ]['height'],
'is_wide' => $this->is_wide_widget( $widget_id ),
)
);
$this->manager->add_control( $control );
}
}
}

Expand Down Expand Up @@ -805,6 +826,72 @@ public function enqueue_scripts() {
'data',
sprintf( 'var _wpCustomizeWidgetsSettings = %s;', wp_json_encode( $settings ) )
);

// TODO: Do we need to do all of the above if block editor is enabled?
// TODO: Maybe this should be a different function?
if ( wp_use_widgets_block_editor() ) {
$block_editor_context = new WP_Block_Editor_Context();
$editor_settings = get_block_editor_settings(
array(
// TODO: DRY this up.
/** This action is documented in widgets-form-blocks.php */
'widgetTypesToHideFromLegacyWidgetBlock' => apply_filters(
'widget_types_to_hide_from_legacy_widget_block',
array(
'pages',
'calendar',
'archives',
'media_audio',
'media_image',
'media_gallery',
'media_video',
'meta',
'search',
'text',
'categories',
'recent-posts',
'recent-comments',
'rss',
'tag_cloud',
'nav_menu',
'custom_html',
'block',
)
),
),
$block_editor_context
);

wp_add_inline_script(
'wp-customize-widgets',
sprintf(
'wp.domReady( function() {
wp.customizeWidgets.initialize( "widgets-customizer", %s );
} );',
wp_json_encode( $editor_settings )
)
);

// Preload server-registered block schemas.
wp_add_inline_script(
'wp-blocks',
'wp.blocks.unstable__bootstrapServerSideBlockDefinitions(' . wp_json_encode( get_block_editor_server_block_settings() ) . ');'
);

wp_add_inline_script(
'wp-blocks',
sprintf( 'wp.blocks.setCategories( %s );', wp_json_encode( get_block_categories( 'widgets-customizer' ) ) ),
'after'
);

wp_enqueue_script( 'wp-customize-widgets' );
wp_enqueue_style( 'wp-customize-widgets' );
wp_enqueue_script( 'wp-format-library' );
wp_enqueue_style( 'wp-format-library' );

/** This action is documented in edit-form-blocks.php */
do_action( 'enqueue_block_editor_assets' );
}
}

/**
Expand Down Expand Up @@ -888,8 +975,13 @@ public function get_setting_args( $id, $overrides = array() ) {
$args['sanitize_js_callback'] = array( $this, 'sanitize_sidebar_widgets_js_instance' );
$args['transport'] = current_theme_supports( 'customize-selective-refresh-widgets' ) ? 'postMessage' : 'refresh';
} elseif ( preg_match( $this->setting_id_patterns['widget_instance'], $id, $matches ) ) {
$args['sanitize_callback'] = array( $this, 'sanitize_widget_instance' );
$args['sanitize_js_callback'] = array( $this, 'sanitize_widget_js_instance' );
$id_base = $matches['id_base'];
$args['sanitize_callback'] = function( $value ) use ( $id_base ) {
return $this->sanitize_widget_instance( $value, $id_base );
};
$args['sanitize_js_callback'] = function( $value ) use ( $id_base ) {
return $this->sanitize_widget_js_instance( $value, $id_base );
};
$args['transport'] = $this->is_widget_selective_refreshable( $matches['id_base'] ) ? 'postMessage' : 'refresh';
}

Expand Down Expand Up @@ -1314,16 +1406,31 @@ protected function get_instance_hash_key( $serialized_instance ) {
* @since 3.9.0
*
* @param array $value Widget instance to sanitize.
* @param string $id_base Base of the ID of the widget being sanitized.
* @return array|void Sanitized widget instance.
*/
public function sanitize_widget_instance( $value ) {
public function sanitize_widget_instance( $value, $id_base = null ) {
global $wp_widget_factory;

if ( array() === $value ) {
return $value;
}

if ( empty( $value['is_widget_customizer_js_value'] )
|| empty( $value['instance_hash_key'] )
|| empty( $value['encoded_serialized_instance'] ) ) {
if ( empty( $value['is_widget_customizer_js_value'] ) ) {
return;
}

if ( isset( $value['raw_instance'] ) && $id_base ) {
$widget_object = $wp_widget_factory->get_widget_object( $id_base );
if ( ! empty( $widget_object->show_instance_in_rest ) ) {
return $value['raw_instance'];
}
}

if (
empty( $value['instance_hash_key'] ) ||
empty( $value['encoded_serialized_instance'] )
) {
return;
}

Expand All @@ -1350,19 +1457,32 @@ public function sanitize_widget_instance( $value ) {
* @since 3.9.0
*
* @param array $value Widget instance to convert to JSON.
* @param string $id_base Base of the ID of the widget being sanitized.
* @return array JSON-converted widget instance.
*/
public function sanitize_widget_js_instance( $value ) {
public function sanitize_widget_js_instance( $value, $id_base = null ) {
global $wp_widget_factory;

if ( empty( $value['is_widget_customizer_js_value'] ) ) {
$serialized = serialize( $value );

$value = array(
$js_value = array(
'encoded_serialized_instance' => base64_encode( $serialized ),
'title' => empty( $value['title'] ) ? '' : $value['title'],
'is_widget_customizer_js_value' => true,
'instance_hash_key' => $this->get_instance_hash_key( $serialized ),
);

if ( $id_base ) {
$widget_object = $wp_widget_factory->get_widget_object( $id_base );
if ( ! empty( $widget_object->show_instance_in_rest ) ) {
$js_value['raw_instance'] = (object) $value;
}
}

return $js_value;
}

return $value;
}

Expand Down Expand Up @@ -1432,7 +1552,7 @@ public function call_widget_update( $widget_id ) {
return new WP_Error( 'widget_setting_malformed' );
}

$instance = $this->sanitize_widget_instance( $sanitized_widget_setting );
$instance = $this->sanitize_widget_instance( $sanitized_widget_setting, $parsed_id['id_base'] );
if ( is_null( $instance ) ) {
$this->stop_capturing_option_updates();
return new WP_Error( 'widget_setting_unsanitized' );
Expand Down Expand Up @@ -1498,7 +1618,7 @@ public function call_widget_update( $widget_id ) {
* in place from WP_Customize_Setting::preview() will use this value
* instead of the default widget instance value (an empty array).
*/
$this->manager->set_post_value( $setting_id, $this->sanitize_widget_js_instance( $instance ) );
$this->manager->set_post_value( $setting_id, $this->sanitize_widget_js_instance( $instance, $parsed_id['id_base'] ) );

// Obtain the widget control with the updated instance in place.
ob_start();
Expand Down Expand Up @@ -1571,7 +1691,7 @@ public function wp_ajax_update_widget() {
}

$form = $updated_widget['form'];
$instance = $this->sanitize_widget_js_instance( $updated_widget['instance'] );
$instance = $this->sanitize_widget_js_instance( $updated_widget['instance'], $id_base );

wp_send_json_success( compact( 'form', 'instance' ) );
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php
/**
* Customize API: WP_Sidebar_Block_Editor_Control class.
*
* @package WordPress
* @subpackage Customize
* @since 5.8.0
*/

/**
* Core class used to implement the widgets block editor control in the
* customizer.
*
* @since 5.8.0
*
* @see WP_Customize_Control
*/
class WP_Sidebar_Block_Editor_Control extends WP_Customize_Control {
/**
* The control type.
*
* @since 5.8.0
*
* @var string
*/
public $type = 'sidebar_block_editor';

/**
* Render the widgets block editor container.
*
* @since 5.8.0
*/
public function render_content() {
// Render an empty control. The JavaScript in
// @wordpress/customize-widgets will do the rest.
}
}
Loading

0 comments on commit 2c74335

Please sign in to comment.