Schema 教程
Schema 教程第10课:从区块中获取结构化数据

第10课:从区块中获取结构化数据

我们可以遍历文章中的(Gutenberg)区块,并从区块结构深处提取属性,从而将这些属性用于网站中的任何功能。

例如,通过提取文章中所有 core/image 区块包含的图片 URL,我们可以用这些图片创建一个图片轮播。

此外,由于区块的属性现在可以在区块编辑器之外广泛访问,我们可以真正将其视为结构化内容,并通过 API 公开,从而为所有应用程序(例如移动应用或新闻邮件)提供支持。

这使我们能够将区块作为所有内容的唯一可信来源,并遵循 COPE("Create Once, Publish Everywhere")策略,将内容分发到不同的媒介和应用程序中。

本教程课程演示如何从文章中所有 core/image 区块中获取图片 URL。

从文章中所有 core/image 区块提取图片 URL

以下 GraphQL query 使用字段 blockFlattenedDataItems 获取文章中的所有区块(包括内部区块),并按 core/image 类型进行过滤。然后遍历所有条目,从每个条目中提取属性 attributes.url,并用其覆盖字段值。最后通过 @arrayUnique 删除重复的 URL(当两个 core/image 区块使用同一张图片时):

query GetImageBlockImageURLs($postID: ID!) {
  post(by: { id: $postID } ) {
    coreImageURLs: blockFlattenedDataItems(
      filterBy: { include: "core/image" }
    )
      @underEachArrayItem(
        passValueOnwardsAs: "blockDataItem"
      )
        @applyField(
          name: "_objectProperty"
          arguments: {
            object: $blockDataItem,
            by: {
              path: "attributes.url"
            }
          }
          setResultInResponse: true
        )
      @arrayUnique
  }
}

响应结果如下:

{
  "data": {
    "post": {
      "coreImageURLs": [
        "https://d.pr/i/fW6V3V+",
        "https://gatographql.lndo.site/wp-content/uploads/2022/05/GatoGraphQL-logo-1024x622.jpg",
        "https://gatographql.lndo.site/wp-content/uploads/2022/05/GatoGraphQL-logo-suki-1024x598.webp"
      ]
    }
  }
}

@underEachArrayItem(由 Field Value Iteration and Manipulation 扩展提供)是一个可组合指令(又称"元指令",即可以包含嵌套指令的指令),它会遍历元素数组,并对每个元素应用其嵌套指令。

@underEachArrayItem 有助于桥接 GraphQL 类型,它可以使返回 [String] 值的字段,被一个接受 String 值作为输入的指令所处理(或其他组合)。

例如,在以下 query 中:

  • 字段 User.capabilities 返回 [String]
  • 指令 @strUpperCase 接受 String

借助 @underEachArrayItem,我们可以将所有 capability 条目转换为大写:

{
  user(by: { id: 3 }) {
    capabilities
      @underEachArrayItem
        @strUpperCase
  }
}

...结果如下:

{
  "data": {
    "user": {
      "capabilities": [
        "LEVEL_0",
        "READ",
        "READ_PRIVATE_EVENTS",
        "READ_PRIVATE_LOCATIONS"
      ]
    }
  }
}