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

如何将WordPress InnerBlocks的HTML存储为父区块属性?

解决FAQ区块JSON-LD生成问题的可行方案

方案一:封装通用递归函数提取嵌套InnerBlocks内容

既然你已经在用render_block过滤器,不用每次手动处理嵌套逻辑,写个通用函数就能一次性提取所有层级的InnerBlocks内容:

function get_all_inner_block_html( $blocks ) {
    $html = '';
    foreach ( $blocks as $block ) {
        // 拼接当前区块的HTML内容
        $html .= $block['innerHTML'];
        // 递归处理嵌套的子区块
        if ( ! empty( $block['innerBlocks'] ) ) {
            $html .= get_all_inner_block_html( $block['innerBlocks'] );
        }
    }
    return $html;
}

// 在render_block过滤器中使用
add_filter( 'render_block', function( $block_content, $block ) {
    // 仅处理你的FAQ区块,替换为实际的区块名称
    if ( 'your-namespace/faq-block' !== $block['blockName'] ) {
        return $block_content;
    }

    $question = isset( $block['attrs']['question'] ) ? $block['attrs']['question'] : '';
    $answer_html = get_all_inner_block_html( $block['innerBlocks'] );

    // 生成JSON-LD结构化数据
    $json_ld = sprintf(
        '<script type="application/ld+json">
        {
            "@context": "https://schema.org",
            "@type": "FAQPage",
            "mainEntity": [{
                "@type": "Question",
                "name": "%s",
                "acceptedAnswer": {
                    "@type": "Answer",
                    "text": "%s"
                }
            }]
        }
        </script>',
        esc_attr( $question ),
        esc_attr( $answer_html )
    );

    // 将JSON-LD注入wp_head
    add_action( 'wp_head', function() use ( $json_ld ) {
        echo $json_ld;
    });

    return $block_content;
}, 10, 2 );

这个函数只需写一次就能复用,不管嵌套多少层InnerBlocks,都会自动拼接所有内容的HTML。

方案二:监听编辑器变化,将InnerBlocks内容存入区块属性

虽然InnerBlocks本身没有value和onChange属性,但可以通过编辑器的数据监听,把InnerBlocks的序列化内容存到区块的content属性中:

在你的Edit.js组件中添加以下代码:

import { useSelect, useDispatch } from '@wordpress/data';
import { useEffect } from '@wordpress/element';

// 在Edit组件内部
const { clientId, setAttributes } = props;
const { getBlock } = useSelect( ( select ) => select( 'core/block-editor' ), [] );
const { updateBlockAttributes } = useDispatch( 'core/block-editor' );

useEffect( () => {
    const currentBlock = getBlock( clientId );
    if ( currentBlock ) {
        // 序列化InnerBlocks内容
        const serializedContent = wp.blocks.serialize( currentBlock.innerBlocks );
        // 更新区块的content属性
        updateBlockAttributes( clientId, { content: serializedContent } );
    }
}, [ clientId, getBlock, updateBlockAttributes ] );

之后在PHP中,直接通过$block['attrs']['content']获取序列化内容,再解析成HTML即可:

$answer_html = wp_kses_post( do_shortcode( $block['attrs']['content'] ) );

注意:这种方式会增加区块属性的存储体积,FAQ场景下影响较小。

方案三:改用服务器端渲染(SSR)区块

如果你的区块适合服务器端渲染,可以在block.json中指定render_callback,直接在PHP中处理内容渲染和JSON-LD生成:

修改block.json:

{
    "apiVersion": 3,
    "name": "your-namespace/faq-block",
    "title": "FAQ Block",
    "category": "widgets",
    "attributes": {
        "question": {
            "type": "string",
            "selector": "h1,h2,h3,h4,h5,h6"
        }
    },
    "editorScript": "file:./index.js",
    "render": "file:./render.php"
}

创建render.php文件:

<?php
$question = isset( $attributes['question'] ) ? $attributes['question'] : '';

// 渲染所有InnerBlocks并获取HTML
ob_start();
echo '<div class="faq-answer">';
foreach ( $inner_blocks as $block ) {
    echo render_block( $block );
}
echo '</div>';
$answer_html = ob_get_clean();

// 生成JSON-LD并注入wp_head
$json_ld = sprintf(
    '<script type="application/ld+json">
    {
        "@context": "https://schema.org",
        "@type": "FAQPage",
        "mainEntity": [{
            "@type": "Question",
            "name": "%s",
            "acceptedAnswer": {
                "@type": "Answer",
                "text": "%s"
            }
        }]
    }
    </script>',
    esc_attr( $question ),
    esc_attr( $answer_html )
);

add_action( 'wp_head', function() use ( $json_ld ) {
    echo $json_ld;
});

// 返回区块前端渲染内容
echo '<div class="faq-block">';
echo '<h3 class="faq-question">' . esc_html( $question ) . '</h3>';
echo $answer_html;
echo '</div>';
?>

这种方式由服务器自动处理所有嵌套区块的渲染,不用手动写递归逻辑,实现更省心。


内容的提问来源于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 19:40:55