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

如何通过GraphQL获取WordPress文章/页面所有嵌套块用于Gatsby开发

解决方案

这里提供两种不同场景下的实现方式,都可以避免手动预设嵌套查询层级:

方案1:无需修改WordPress后端,直接使用内置JSON字段

WPGraphQL默认提供blocksJSON字段,会返回包含所有层级嵌套块的完整JSON结构,不需要手动预设嵌套层级,查询语句可以简化为:

query MyQuery {
  page(id: "36889", idType: DATABASE_ID) {
    id
    blocksJSON
  }
}

拿到返回结果后,只需要在Gatsby侧用JSON.parse()解析blocksJSON,再写个简单的递归函数遍历所有块,就能把任意深度的所有块提取为平级列表,参考实现代码:

// 递归提取所有块的工具函数
const getAllBlocks = (blocks) => {
  let allBlocks = []
  for (const block of blocks) {
    allBlocks.push(block)
    if (block.innerBlocks?.length) {
      allBlocks = allBlocks.concat(getAllBlocks(block.innerBlocks))
    }
  }
  return allBlocks
}

// 使用示例
const blocks = JSON.parse(page.blocksJSON)
const allBlocksList = getAllBlocks(blocks)

该方案改造成本极低,不需要调整WordPress端配置,完全在Gatsby侧即可完成处理。

方案2:优化查询性能,WordPress端提前返回扁平化块

如果希望减少Gatsby侧的计算量,可以在WordPress主题的functions.php中注册自定义字段,提前递归遍历所有块返回平级列表,之后直接在GraphQL中查询该字段即可:

// 注册自定义扁平化块字段
add_action('graphql_register_types', function () {
  register_graphql_field('ContentNode', 'allFlatBlocks', [
    'type' => ['list_of' => 'Block'],
    'description' => '返回所有层级的扁平化块列表',
    'resolve' => function ($post) {
      $blocks = parse_blocks($post->post_content);
      $flatBlocks = [];
      
      $flatten = function ($blocks) use (&$flatBlocks, &$flatten) {
        foreach ($blocks as $block) {
          if (!empty($block['blockName'])) {
            $flatBlocks[] = $block;
          }
          if (!empty($block['innerBlocks'])) {
            $flatten($block['innerBlocks']);
          }
        }
      };
      
      $flatten($blocks);
      return $flatBlocks;
    }
  ]);
});

注册完成后,你的GraphQL查询可以简化为:

query MyQuery {
  page(id: "36889", idType: DATABASE_ID) {
    id
    allFlatBlocks {
      name
      attributes
    }
  }
}

直接就能拿到所有层级的块列表,无需额外处理。

内容的提问来源于stack exchange,提问作者Ben Upham

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 01:06:08