如何通过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
相关产品推荐
相关产品推荐

