Skip to content

Commit

Permalink
Merge pull request #60 from Automattic/add/pre-content-filter
Browse files Browse the repository at this point in the history
Add pre- and post- content filter
  • Loading branch information
alecgeatches authored Apr 9, 2024
2 parents 4c58623 + c547220 commit 1c5ef3b
Show file tree
Hide file tree
Showing 6 changed files with 320 additions and 134 deletions.
93 changes: 93 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -1218,6 +1218,99 @@ Direct block HTML can be accessed through `$block['innerHTML']`. This may be use
For another example of how this filter can be used to extend block data, we have implemented a default image block filter in [`src/parser/block-additions/core-image.php`][repo-core-image-block-addition]. This filter is automatically called on `core/image` blocks to add `width` and `height` to image attributes.
---
### `vip_block_data_api__before_parse_post_content`
Modify raw post content before it's parsed by the Block Data API. The `$post_content` provided by this filter is directly what is stored in the post database before any processing occurs.
```php
/**
* Filters content before parsing blocks in a post.
*
* @param string $post_content The content of the post being parsed.
* @param int $post_id Post ID associated with the content.
*/
$post_content = apply_filters( 'vip_block_data_api__before_parse_post_content', $post_content, $post_id );
```
For example, this could be used to modify a block's type before parsing. The code below replaces instances of `test/invalid-block` blocks with `core/paragraph`:
```php
add_filter( 'vip_block_data_api__before_parse_post_content', 'replace_invalid_blocks' );
function replace_invalid_blocks( $post_content, $post_id ) {
return str_replace( 'wp:test/invalid-block', 'wp:paragraph', $post_content );
}
$html = '
<!-- wp:test/invalid-block -->
<p>Block content!</p>
<!-- /wp:test/invalid-block -->
';
$content_parser = new ContentParser();
$result = $content_parser->parse( $html );
// Evaluates to true
assertEquals( [
[
'name' => 'core/paragraph',
'attributes' => [
'content' => 'Block content!',
],
],
], $result['blocks'] );
```
**Warning**
Be careful with content modification before parsing. In the example above, if a block contained the text "wp:test/invalid-block" outside of a block header, this would also be changed to "wp:paragraph". This is likely not the intent of the code.
All block markup is sensitive to changes, even changes in whitespace. We've added this filter to make the plugin flexible, but any transforms to `post_content` should be done with extreme care. Strongly consider adding tests to any usage of this filter.
---
### `vip_block_data_api__after_parse_blocks`
Modify the Block Data API REST endpoint response.
```php
/**
* Filters the API result before returning parsed blocks in a post.
*
* @param string $result The successful API result, contains 'blocks' key with an array
* of block data, and optionally 'warnings' and 'debug' keys.
* @param int $post_id Post ID associated with the content.
*/
$result = apply_filters( 'vip_block_data_api__after_parse_blocks', $result, $post_id );
```
This filter is called directly before returning a result in the REST API. Use this filter to add additional metadata or debug information to the API output.
```php
add_action( 'vip_block_data_api__after_parse_blocks', 'add_block_data_debug_info', 10, 2 );
function add_block_data_debug_info( $result, $post_id ) {
$result['debug']['my-value'] = 123;
return $result;
}
```
This would add `debug.my-value` to all Block Data API REST results:
```bash
> curl https://my.site/wp-json/vip-block-data-api/v1/posts/1/blocks
{
"debug": {
"my-value": 123
},
"blocks": [ /* ... */ ]
}
```
## Analytics
**Please note that, this is for VIP sites only. Analytics are disabled if this plugin is not being run on VIP sites.**
Expand Down
17 changes: 17 additions & 0 deletions src/parser/content-parser.php
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,14 @@ public function parse( $post_content, $post_id = null, $filter_options = [] ) {
$parsing_error = false;

try {
/**
* Filters content before parsing blocks in a post.
*
* @param string $post_content The content of the post being parsed.
* @param int $post_id Post ID associated with the content.
*/
$post_content = apply_filters( 'vip_block_data_api__before_parse_post_content', $post_content, $post_id );

$blocks = parse_blocks( $post_content );
$blocks = array_values( array_filter( $blocks, function ( $block ) {
$is_whitespace_block = ( null === $block['blockName'] && empty( trim( $block['innerHTML'] ) ) );
Expand Down Expand Up @@ -168,6 +176,15 @@ public function parse( $post_content, $post_id = null, $filter_options = [] ) {
'details' => $parsing_error->__toString(),
] );
} else {
/**
* Filters the API result before returning parsed blocks in a post.
*
* @param string $result The successful API result, contains 'blocks'
* key with an array of block data, and optionally 'warnings' and 'debug' keys.
* @param int $post_id Post ID associated with the content.
*/
$result = apply_filters( 'vip_block_data_api__after_parse_blocks', $result, $post_id );

return $result;
}
}
Expand Down
Loading

0 comments on commit 1c5ef3b

Please sign in to comment.