You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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>

如果还是拿不到属性,检查:

  1. 编辑器端是否正确绑定了setAttributes更新question属性
  2. 保存文章后,查看数据库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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 17:43:19