cloakwp / block-parser
解析 Gutenberg + ACF Blocks 到结构化对象。
Requires
- php: >=7.4
- cloakwp/hook-modifiers: *
- composer/installers: ^2.2
- franzl/studio: *
- tburry/pquery: ^1.1
README
CloakWP Block Parser 是一个 PHP 库,用于解析和转换 Gutenberg 和 ACF Blocks 到结构化对象/JSON。此包是 CloakWP 生态系统的一部分,但也可以独立使用或作为您自己的插件/主题/软件包的依赖项。
特性
- 解析 Gutenberg (核心) Blocks 到对象/JSON
- 解析 Advanced Custom Fields (ACF) Blocks 到对象/JSON
- 可扩展的架构,用于自定义块转换器
- 过滤器用于修改解析的块数据
动机
WordPress 块内容以 HTML 字符串的形式存储在数据库中,而不是结构化数据(例如 JSON)。这在解耦/无头项目中尤其成问题,在这些项目中,您可能希望以自己的方式渲染内容;为此,您需要以 JSON/结构化对象形式获取块 -- 结果表明,这出奇地难以实现。CloakWP Block Parser 通过提供一种干净和有组织的方式来解析和转换块内容为结构化数据,简化了这一过程。
安装
您可以通过 Composer 安装此包
composer require cloakwp/block-parser
示例输出
结构化数据
[
{
"name": "core/paragraph",
"type": "core",
"attrs": {
"content": "Contact us via phone <a href=\"tel:123-456-7890\">(123) 456-7890</a> or email <a href=\"mailto:info@example.com\">info@example.com</a>.",
"dropCap": false
}
},
{
"name": "acf/hero",
"type": "acf",
"attrs": {
"style": {
"spacing": {
"margin": {
"bottom": "var:preset|spacing|60"
}
}
},
"className": "pb-8 md:pb-10",
"align": "full",
"backgroundColor": "bg-root-dim"
},
// ACF field data:
"data": {
"hero_style": "image_right",
"image": {
"medium": {
"src": "https:///app/uploads/sites/8/2024/08/example-300x200.jpeg",
"width": 300,
"height": 200
},
"large": {
"src": "https:///app/uploads/sites/8/2024/08/example-1024x683.jpeg",
"width": 1024,
"height": 683
},
"full": {
"src": "https:///app/uploads/sites/8/2024/08/example.jpeg",
"width": 1620,
"height": 1080
},
"alt": "example alt description",
"caption": "example caption"
},
"eyebrow": "WordPress Experts",
"h1": "Build your dream website.",
"subtitle": "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.",
"cta_buttons": false,
"show_social_proof": false
}
}
]
使用方法
基本使用
use CloakWP\BlockParser\BlockParser; $postId = 123; $blockParser = new BlockParser(); $blockData = $blockParser->parseBlocksFromPost($postId);
扩展
自定义转换器
BlockParser 使用内置的核心函数 parse_blocks() 来初始解析块,但遗憾的是,这个函数并没有完成所有工作。因此,我们通过块 "转换器" 扩展了基本的内置解析。
默认情况下,BlockParser 使用以下转换器
- CoreBlockTransformer(用于 Gutenberg 核心块)
- ACFBlockTransformer(用于 ACF 块)
您可以通过注册自定义块转换器来扩展 BlockParser,为某些块类型添加逻辑,或覆盖默认转换器
// when you define your Transformer class, you must implement the BlockTransformerInterface and define // a static $type property, which indicates the block type that the transformer should be applied to: class MyCustomACFBlockTransformer implements BlockTransformerInterface { protected static string $type = 'acf'; // this will override the default ACFBlockTransformer public function transform(WP_Block $block, int|null $postId = null): array { // your custom data transformation code here -- whatever you return here will be the final block data } } // now register the transformer with your BlockParser instance: $blockParser = new BlockParser(); $blockParser->registerBlockTransformer(MyCustomACFBlockTransformer::class);
如果在上面的示例中您想为某些自定义块类型添加转换器,只需为静态 $type 属性指定一个自定义值,然后扩展 BlockParser 类并重写 determineBlockType() 方法来添加您自己的逻辑以确定块是否为您的自定义类型;例如
class MyCustomBlockParser extends BlockParser { protected function determineBlockType(WP_Block $block): string { if ($block->blockName === 'my-custom-block-name') { return 'custom'; } return parent::determineBlockType($block); } } class MyCustomBlockTransformer implements BlockTransformerInterface { protected static string $type = 'custom'; public function transform(WP_Block $block, int|null $postId = null): array { // .. } } $postId = 123; $blockParser = new MyCustomBlockParser(); $blockParser->registerBlockTransformer(MyCustomBlockTransformer::class) // now any blocks with name 'my-custom-block-name' will be transformed by MyCustomBlockTransformer's transform() method $blockData = $blockParser->parseBlocksFromPost($postId);
过滤器钩子
除了创建自定义转换器外,您还可以使用过滤器修改解析的块数据。这些过滤器在块被适当的转换器转换后应用,但在块返回之前
add_filter('cloakwp/block', function(array $parsedBlock, WP_Block $wpBlock) { // modify $parsedBlock here return $parsedBlock; }, 10, 2);
cloakwp/block 过滤器接受两个修饰符,name 和 type,以实现更细粒度的定位
add_filter('cloakwp/block/name=core/paragraph', function(array $parsedBlock, WP_Block $wpBlock) { // modify $parsedBlock here return $parsedBlock; }, 10, 2); add_filter('cloakwp/block/type=acf', function(array $parsedBlock, WP_Block $wpBlock) { // modify $parsedBlock here return $parsedBlock; }, 10, 2);
您还可以使用 cloakwp/block/field 过滤器过滤 ACF 块内的 ACF 字段值
add_filter('cloakwp/block/field', function(mixed $fieldValue, array $fieldObject) { // modify $fieldValue here return $fieldValue; }, 10, 2);
cloakwp/block/field 过滤器接受三个修饰符,name(即 ACF 字段名称)、type(即 ACF 字段类型)和 blockName(即 ACF 块名称),以实现更细粒度的定位
add_filter('cloakwp/block/field/name=my_acf_field', function(mixed $fieldValue, array $fieldObject) { // modify $fieldValue here return $fieldValue; }, 10, 2); add_filter('cloakwp/block/field/type=image', function(mixed $fieldValue, array $fieldObject) { // modify $fieldValue here return $fieldValue; }, 10, 2); add_filter('cloakwp/block/field/blockName=acf/hero-section', function(mixed $fieldValue, array $fieldObject) { // modify $fieldValue here return $fieldValue; }, 10, 2);