Skip to content
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

Experiment: Auto-inserting blocks on the frontend #50103

Closed
wants to merge 39 commits into from
Closed
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
39 commits
Select commit Hold shift + click to select a range
a9b1993
Insert a string after each comment-content block
ockham Apr 26, 2023
6ac30c1
Use an actual block
ockham Apr 26, 2023
03ebf7e
Start implementing basic last-child mechanism
ockham Apr 26, 2023
9382109
Bit of polish
ockham Apr 26, 2023
01de9dc
More polish
ockham Apr 26, 2023
df6cf73
More polish
ockham Apr 27, 2023
9db02c3
Consistency
ockham Apr 27, 2023
9a46647
Formatting
ockham May 2, 2023
d1b0225
Auto-insert Avatar block under comments
ockham May 2, 2023
6f36442
Use render_block_data filter to insert child block
ockham May 31, 2023
02883ef
Make child block insertion more flexible
ockham May 31, 2023
8bd8c6d
Remove child block insertion from render_block hook
ockham May 31, 2023
e1fde47
Simplify render_block logic
ockham May 31, 2023
9e36ff1
Comment typo
ockham May 31, 2023
1188192
Switch places
ockham May 31, 2023
e8161e8
Insert Social Icon after Post Content
ockham May 31, 2023
05f3bd4
Add comment to render_block hook
ockham May 31, 2023
db0434d
Remove now-obsolete filter args
ockham May 31, 2023
829806e
A bit nicer still
ockham May 31, 2023
da7290d
Manually create inserted block
ockham May 31, 2023
4076c4e
Formatting
ockham May 31, 2023
97fbbae
Fix unit test
ockham May 31, 2023
8b78c34
A bit easier on the eye
ockham Jun 1, 2023
8e9c832
Use null rather than block instance in innerContent
ockham Jun 1, 2023
3666509
A bit nicer to read yet
ockham Jun 5, 2023
2f5f385
Add autoInsert field to block.json schema
ockham Jun 6, 2023
1f7efb4
More precise schema
ockham Jun 6, 2023
d5ab6d1
Just before/after
ockham Jun 6, 2023
9ee00d2
Extract auto-insert settings from metadata
ockham Jun 6, 2023
4495304
Nicer syntax
ockham Jun 6, 2023
4281152
Leverage block-specific render_block hook
ockham Jun 6, 2023
50a63e4
Insert block dynamically
ockham Jun 6, 2023
236dc32
Insert block after Post Content
ockham Jun 6, 2023
2ae6616
Change syntax again
ockham Jun 6, 2023
b3ad57b
Revert "Change syntax again"
ockham Jun 7, 2023
411f160
Add comment about auto-inserted blocks registry
ockham Jun 7, 2023
8bd4f28
Use analog mechanism for child block insertion
ockham Jun 7, 2023
46e30e5
Support block attributes
ockham Jun 7, 2023
023d652
Rename gutenberg_auto_insert_blocks to gutenberg_auto_insert_block
ockham Jun 13, 2023
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
74 changes: 74 additions & 0 deletions lib/experimental/blocks.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,3 +100,77 @@ function gutenberg_register_metadata_attribute( $args ) {
return $args;
}
add_filter( 'register_block_type_args', 'gutenberg_register_metadata_attribute' );

/**
* Auto-insert a block as another block's first or last inner block.
*
* @param array $parsed_block The block being rendered.
*/
function gutenberg_auto_insert_child_block( $parsed_block ) {
// TODO: Implement an API for users to set the following two parameters.
$block_name = 'core/comment-template';
$block_position = 'last-child';

if ( $block_name === $parsed_block['blockName'] ) {
// parse_blocks( '<!-- wp:avatar {"size":40,"style":{"border":{"radius":"10px"}}} /-->' )[0].
$inserted_block = array(
'blockName' => 'core/avatar',
'attrs' => array(
'size' => 40,
'style' => array(
'border' => array( 'radius' => '10px' ),
),
),
'innerHTML' => '',
'innerContent' => array(),
);

if ( 'first-child' === $block_position ) {
array_unshift( $parsed_block['innerBlocks'], $inserted_block );
// Since WP_Block::render() iterates over `inner_content` (rather than `inner_blocks`)
// when rendering blocks, we also need to prepend the new block to that array.
array_unshift( $parsed_block['innerContent'], $inserted_block );
ockham marked this conversation as resolved.
Show resolved Hide resolved
} elseif ( 'last-child' === $block_position ) {
array_push( $parsed_block['innerBlocks'], $inserted_block );
// Since WP_Block::render() iterates over `inner_content` (rather than `inner_blocks`)
// when rendering blocks, we also need to append the new block to that array.
array_push( $parsed_block['innerContent'], $inserted_block );
}
}
return $parsed_block;
}
add_filter( 'render_block_data', 'gutenberg_auto_insert_child_block', 10, 1 );

/**
* Auto-insert blocks relative to a given block.
*
* @param string $block_content The block content.
* @param array $block The full block, including name and attributes.
*/
function gutenberg_auto_insert_blocks( $block_content, $block ) {
// TODO: Implement an API for users to set the following two parameters.
$block_name = 'core/post-content';
$block_position = 'after';

// Can we avoid infinite loops?

if ( $block_name === $block['blockName'] ) {
$inserted_block_markup = <<<END
<!-- wp:social-links -->
<ul class="wp-block-social-links"><!-- wp:social-link {"url":"https://wordpress.org","service":"wordpress"} /--></ul>
<!-- /wp:social-links -->'
END;

$inserted_blocks = parse_blocks( $inserted_block_markup );
$inserted_content = render_block( $inserted_blocks[0] );

if ( 'before' === $block_position ) {
$block_content = $inserted_content . $block_content;
} elseif ( 'after' === $block_position ) {
$block_content = $block_content . $inserted_content;
}
}

return $block_content;
}
add_filter( 'render_block', 'gutenberg_auto_insert_blocks', 10, 2 );
5 changes: 5 additions & 0 deletions phpunit/blocks/render-comment-template-test.php
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,9 @@ public function test_inner_block_inserted_by_render_block_data_is_retained() {
return $parsed_block;
};

// Remove auto-insertion filter so it won't collide.
remove_filter( 'render_block_data', 'gutenberg_auto_insert_child_block' );

add_filter( 'render_block_data', $render_block_data_callback, 10, 1 );
$parsed_blocks = parse_blocks(
'<!-- wp:comments --><!-- wp:comment-template --><!-- wp:comment-content /--><!-- /wp:comment-template --><!-- /wp:comments -->'
Expand All @@ -154,6 +157,8 @@ public function test_inner_block_inserted_by_render_block_data_is_retained() {
);
$block->render();
remove_filter( 'render_block_data', $render_block_data_callback );
// Add back auto-insertion filter.
add_filter( 'render_block_data', 'gutenberg_auto_insert_child_block', 10, 1 );

$this->assertSame( 5, $render_block_callback->get_call_count() );

Expand Down