Skip to content
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Lib: Implement server-side block context.
  • Loading branch information
epiqueras authored and aduth committed Apr 6, 2020
commit 9461576bbbc3c418cb2cbb1ebd89dc6e6364daff
72 changes: 72 additions & 0 deletions lib/compat.php
Original file line number Diff line number Diff line change
Expand Up @@ -125,3 +125,75 @@ function gutenberg_get_post_from_context() {
}
return get_post();
}

/**
* Shim that hooks into `pre_render_block` so as to override `render_block`
* with a function that passes `render_callback` the block object as an
* argument and adds support for block context attributes.
*
* @param string $pre_render The pre-rendered content. Defaults to null.
* @param array $block The block being rendered.
* @param array $context The block context.
*
* @return string String of rendered HTML.
*/
function gutenberg_provide_render_callback_with_block_object( $pre_render, $block, $context = array() ) {
global $post;

$source_block = $block;
/** This filter is documented in src/wp-includes/blocks.php */
$block = apply_filters( 'render_block_data', $block, $source_block );
$block_type = WP_Block_Type_Registry::get_instance()->get_registered( $block['blockName'] );
$is_dynamic = $block['blockName'] && null !== $block_type && $block_type->is_dynamic();
$block_content = '';
$index = 0;

if ( ! is_array( $block['attrs'] ) ) {
$block['attrs'] = array();
}

$block['context'] = array();
$next_context = $context;
if ( $block_type ) {
if ( isset( $block_type->context ) ) {
foreach ( $block_type->context as $attribute_name => $block_names ) {
$block_names = is_array( $block_names ) ? $block_names : array( $block_names );
foreach ( $block_names as $block_name ) {
if ( isset( $context[ $block_name ][ $attribute_name ] ) ) {
$block['context'][ $attribute_name ] = $context[ $block_name ][ $attribute_name ];
}
}
}
}
if ( isset( $block_type->attributes ) ) {
foreach ( $block_type->attributes as $attribute_name => $attribute_config ) {
if ( $attribute_config['context'] && isset( $block['attrs'][ $attribute_name ] ) ) {
if ( ! isset( $next_context[ $block['blockName'] ] ) ) {
$next_context[ $block['blockName'] ] = array();
}
$next_context[ $block['blockName'] ][ $attribute_name ] = $block['attrs'][ $attribute_name ];
}
}
}
}

foreach ( $block['innerContent'] as $chunk ) {
if ( is_string( $chunk ) ) {
$block_content .= $chunk;
} else {
$inner_block = $block['innerBlocks'][ $index++ ];
$block_content .= gutenberg_provide_render_callback_with_block_object( null, $inner_block, $next_context );
}
}

if ( $is_dynamic ) {
$global_post = $post;

$prepared_attributes = $block_type->prepare_attributes_for_render( $block['attrs'] );
$block_content = (string) call_user_func( $block_type->render_callback, $prepared_attributes, $block_content, $block );
$post = $global_post;
}
/** This filter is documented in src/wp-includes/blocks.php */
return apply_filters( 'render_block', $block_content, $block );
}
add_filter( 'pre_render_block', 'gutenberg_provide_render_callback_with_block_object', 10, 2 );