如何在PHP中获取WordPress自定义区块属性以生成JSON Schema
解决WordPress自定义FAQ区块生成JSON-LD Schema的PHP方案
核心问题定位
你之前拿不到区块属性,大概率是block.json的属性定义不规范,导致WordPress没有把属性保存到文章的区块数据中;另外,直接解析原始区块数据比过滤渲染后的HTML靠谱得多。
步骤1:修正区块属性定义(关键)
确保你的FAQ区块的block.json里,正确定义需要提取的属性,让WordPress自动保存到数据库的区块注释中:
{ "$schema": "https://schemas.wp.org/trunk/block.json", "apiVersion": 3, "name": "your-plugin/faq-block", // 替换成你的区块名称 "title": "FAQ 项", "category": "common", "icon": "editor-help", "attributes": { "question": { "type": "string", "default": "", "description": "FAQ问题文本" } }, "supports": { "html": false }, "editorScript": "file:./index.js", "renderCallback": "render_faq_block" // 用PHP渲染回调更灵活 }
同时,编辑器端(index.js)要把输入的问题绑定到区块属性,确保保存时写入数据库:
import { useBlockProps, RichText, InnerBlocks } from '@wordpress/block-editor'; export default function Edit({ attributes, setAttributes }) { const blockProps = useBlockProps(); return ( <div {...blockProps}> <RichText tagName="h3" placeholder="输入FAQ问题..." value={attributes.question} onChange={(val) => setAttributes({ question: val })} className="faq-question" /> <InnerBlocks allowedBlocks={['core/paragraph']} /> </div> ); }
步骤2:PHP提取区块数据并生成JSON-LD
通过parse_blocks()直接解析文章的原始区块数据,筛选FAQ区块,提取属性和InnerBlocks内容,然后通过wp_head钩子输出到<head>:
function output_faq_schema() { // 仅在单篇文章/页面执行 if ( ! is_singular() ) return; global $post; $blocks = parse_blocks( $post->post_content ); $faq_items = []; foreach ( $blocks as $block ) { // 匹配你的FAQ区块名称 if ( $block['blockName'] !== 'your-plugin/faq-block' ) continue; // 提取问题属性 $question = isset( $block['attrs']['question'] ) ? sanitize_text_field( $block['attrs']['question'] ) : ''; if ( empty( $question ) ) continue; // 处理InnerBlocks内容:渲染后清理HTML,或保留允许的标签 $answer = ''; if ( ! empty( $block['innerBlocks'] ) ) { // 方案1:提取纯文本(适合Schema) $answer = wp_strip_all_tags( render_block( $block['innerBlocks'] ), true ); // 方案2:保留合法HTML(如<p>、<ul>) // $answer = wp_kses( render_block( $block['innerBlocks'] ), wp_kses_allowed_html( 'post' ) ); } if ( empty( $answer ) ) continue; $faq_items[] = [ '@type' => 'Question', 'name' => $question, 'acceptedAnswer' => [ '@type' => 'Answer', 'text' => $answer ] ]; } // 输出Schema到<head> if ( ! empty( $faq_items ) ) { $schema = [ '@context' => 'https://schema.org', '@type' => 'FAQPage', 'mainEntity' => $faq_items ]; echo '<script type="application/ld+json">' . wp_json_encode( $schema ) . '</script>'; } } add_action( 'wp_head', 'output_faq_schema' );
步骤3:修复render.php的属性接收问题
如果用render.php作为渲染模板,确保正确接收$attributes参数(WordPress会自动传递解析后的属性):
<?php // render.php $question = isset( $attributes['question'] ) ? esc_html( $attributes['question'] ) : ''; ?> <div class="faq-item"> <h3 class="faq-question"><?php echo $question; ?></h3> <div class="faq-answer"><?php echo $content; ?></div> </div>
如果还是拿不到属性,检查:
- 编辑器端是否正确绑定了
setAttributes更新question属性 - 保存文章后,查看数据库
wp_posts表中该文章的post_content,是否包含<!-- wp:your-plugin/faq-block {"question":"xxx"} -->这样的注释
为什么之前的方法不行?
- JS生成Schema:搜索引擎可能不会执行JS,导致无法抓取到Schema数据,确实不合适
- OB_Clean过滤HTML:依赖渲染后的DOM结构,一旦区块样式或结构修改就会失效,维护成本高
- 直接解析区块原始数据:WordPress的
parse_blocks()是官方提供的区块解析API,最可靠且符合规范
内容的提问来源于stack exchange,提问作者Walrus
相关产品推荐
相关产品推荐

