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

Add pre- and post- content filter #60

Merged
merged 9 commits into from
Apr 9, 2024
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
Loading