Skip to content

Commit

Permalink
Render widget areas referencing blocks in a wp_area post on the websi…
Browse files Browse the repository at this point in the history
…te frontend.
  • Loading branch information
jorgefilipecosta committed May 22, 2019
1 parent c53f621 commit ee18b08
Show file tree
Hide file tree
Showing 2 changed files with 103 additions and 3 deletions.
21 changes: 18 additions & 3 deletions lib/class-experimental-wp-widget-blocks-manager.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,18 @@ public static function get_wp_registered_sidebars_sidebar( $sidebar_id ) {
return $wp_registered_sidebars[ $sidebar_id ];
}

/**
* Returns the result of wp_get_sidebars_widgets without gutenberg_swap_out_sidebars_blocks_for_block_widgets filter being applied.
*
* @since 5.7.0
*/
private static function get_raw_sidebar_widgets() {
remove_filter( 'sidebars_widgets', 'gutenberg_swap_out_sidebars_blocks_for_block_widgets' );
$sidebars_widgets = wp_get_sidebars_widgets();
add_filter( 'sidebars_widgets', 'gutenberg_swap_out_sidebars_blocks_for_block_widgets' );
return $sidebars_widgets;
}

/**
* Returns a post id being referenced in a sidebar area.
*
Expand All @@ -59,7 +71,7 @@ public static function get_wp_registered_sidebars_sidebar( $sidebar_id ) {
* @return integer Post id.
*/
public static function get_post_id_referenced_in_sidebar( $sidebar_id ) {
$sidebars = wp_get_sidebars_widgets();
$sidebars = self::get_raw_sidebar_widgets();
$sidebar = $sidebars[ $sidebar_id ];
return is_numeric( $sidebar ) ? $sidebar : 0;
}
Expand All @@ -73,7 +85,7 @@ public static function get_post_id_referenced_in_sidebar( $sidebar_id ) {
* @param integer $post_id Post id.
*/
public static function reference_post_id_in_sidebar( $sidebar_id, $post_id ) {
$sidebars = wp_get_sidebars_widgets();
$sidebars = self::get_raw_sidebar_widgets();
$sidebar = $sidebars[ $sidebar_id ];
wp_set_sidebars_widgets(
array_merge(
Expand All @@ -100,7 +112,7 @@ public static function reference_post_id_in_sidebar( $sidebar_id, $post_id ) {
public static function get_sidebar_as_blocks( $sidebar_id ) {
$blocks = array();

$sidebars_items = wp_get_sidebars_widgets();
$sidebars_items = self::get_raw_sidebar_widgets();

foreach ( $sidebars_items[ $sidebar_id ] as $item ) {
$widget_class = self::get_widget_class( $item );
Expand Down Expand Up @@ -245,6 +257,9 @@ public static function serialize_blocks( $blocks ) {
* @return string String representing the block.
*/
public static function serialize_block( $block ) {
if( ! isset( $block[ 'blockName' ] ) ) {
return '';
}
$name = $block['blockName'];
if ( 0 === strpos( $name, 'core/' ) ) {
$name = substr( $name, strlen( 'core/' ) );
Expand Down
85 changes: 85 additions & 0 deletions lib/widgets.php
Original file line number Diff line number Diff line change
Expand Up @@ -181,3 +181,88 @@ function gutenberg_create_wp_area_post_type() {
);
}
add_action( 'init', 'gutenberg_create_wp_area_post_type' );

/**
* Outputs a block widget on the website frontend.
*
* @param array $options Widget options.
* @param array $arguments Arguments array.
*/
function gutenberg_output_blocks_widget( $options, $arguments ) {
echo $options['before_widget'];
foreach( $arguments['blocks'] as $block ) {
echo render_block( $block );
}
echo $options['after_widget'];
}

/**
* Registers of a widget that should represent a set of blocks and returns its id.
*
* @param array $blocks Array of blocks.
*/
function gutenberg_blocks_to_widget( $blocks ) {
$widget_id = 'blocks-widget-' . md5( Experimental_WP_Widget_Blocks_Manager::serialize_block( $blocks ) );
global $wp_registered_widgets;
if ( isset( $wp_registered_widgets[ $widget_id ] ) ) {
return $widget_id;
}
wp_register_sidebar_widget(
$widget_id,
__( 'Blocks Area ', 'gutenberg' ),
'gutenberg_output_blocks_widget',
array(
'classname' => 'widget-area',
'description' => __( 'Displays a set of blocks', 'gutenberg' ),
),
array(
'blocks' => $blocks,
)
);
return $widget_id;
}

/**
* Filters the $sidebars_widgets to exchange wp_area post id with a widget that renders that block area.
*
* @param array $sidebars_widgets An associative array of sidebars and their widgets.
* @return array Filtered associative array of sidebars and their widgets.
*/
function gutenberg_swap_out_sidebars_blocks_for_block_widgets( $sidebars_widgets ) {
global $wp_registered_widgets;
foreach ( $sidebars_widgets as $sidebar_id => $item ) {
if ( ! is_numeric( $item ) ) {
continue;
}

$filtered_widgets = array();
$last_set_of_blocks = array();
$post = get_post( $item );
$blocks = parse_blocks( $post->post_content );

foreach ( $blocks as $block ) {
if ( ! isset( $block['blockName'] ) ) {
continue;
}
if (
'core/legacy-widget' === $block['blockName'] &&
isset( $block['attrs']['identifier'] )
) {
if ( ! empty( $last_set_of_blocks ) ) {
$filtered_widgets[] = gutenberg_blocks_to_widget( $last_set_of_blocks );
$last_set_of_blocks = array();
}
$filtered_widgets[] = $block['attrs']['identifier'];
} else {
$last_set_of_blocks[] = $block;
}
}
if ( ! empty( $last_set_of_blocks ) ) {
$filtered_widgets[] = gutenberg_blocks_to_widget( $last_set_of_blocks );
}

$sidebars_widgets[ $sidebar_id ] = $filtered_widgets;
}
return $sidebars_widgets;
}
add_filter( 'sidebars_widgets', 'gutenberg_swap_out_sidebars_blocks_for_block_widgets' );

0 comments on commit ee18b08

Please sign in to comment.