构建页面

如何使用来自 Drupal 的 JSON:API 资源构建页面。


在 Next.js 中,您可以在 getStaticPropsgetServerSideProps 中获取服务器端数据。然后将数据提供给您的页面进行预渲染。

DrupalClient 提供了一些函数来帮助您查询来自 Drupal 的 JSON:API 资源。


基本示例

这是一个使用 getResource 通过 ID 获取 page 节点的示例

const node = await drupal.getResource(
"node--page",
"07464e9f-9221-4a4f-b7f2-01389408e6c8"
)

完整的页面如下所示

pages/about.tsx

// node will be populated at build time by getStaticProps
export default function AboutPage({ node }) {
return (
<article>
<h1>{node.title}</h1>
// ...
</article>
)
}
export async function getStaticProps() {
// Fetch the node from Drupal.
const node = await drupal.getResource(
"node--page",
"07464e9f-9221-4a4f-b7f2-01389408e6c8"
)
// Pass the node as props to the AboutPage.
return {
props: {
node,
},
}
}

动态页面

您可以使用 Next.js 的 动态路由 为 Drupal 实体类型构建静态页面。

首先,在 /pages/[...slug].tsx 创建一个页面,其中 [...slug] 映射到 Drupal 中实体类型(或内容类型)的**路径别名**。

这意味着 /pages/[...slug].tsx 将处理所有具有以下别名的页面:/about/team/another/path 等。

要构建静态页面,我们需要实现两个函数。

  1. getStaticPaths:告诉 Next.js 我们想要渲染的所有路由。
  2. getStaticProps:获取页面数据。

pages/[...slug].tsx

export default function Page({ node }) {
return (
<article>
<h1>{node.title}</h1>
// ...
</article>
)
}
export async function getStaticPaths(context) {
// Build paths for all `node--page`.
return {
paths: await drupal.getStaticPathsFromContext("node--page", context),
fallback: false,
}
}
export async function getStaticProps(context) {
// Fetch the node based on the context.
// next-drupal automatically handles the slug value.
const node = await drupal.getResourceFromContext("node--page", context)
return {
props: {
node,
},
}
}

高级示例

在上面的示例中,我们使用 pages/[...slug].tsxnode--page 构建静态页面。

我们可以更进一步,在一个页面中处理所有节点类型(或任何实体类型)。

为此,我们将使用 translatePathFromContext,它根据 context 中的 slug 值返回有关资源类型的信息。

export async function getStaticProps(context) {
const path = await drupal.translatePathFromContext(context)
// Get the resource type.
const type = path.jsonapi.resourceName
if (type === "node--article") {
// Build custom JSON:API query for article.
}
if (type === "node--page") {
// Build custom JSON:API query for page.
}
}

让我们更新 pages/[...slug].tsx 以同时处理 node--pagenode--article

pages/[...slug].tsx

import { DrupalJsonApiParams } from "drupal-jsonapi-params"
export default function Page({ node }) {
if (node.type === "node--page") {
return <PageComponent />
}
if (node.type === "node--article") {
return <ArticleComponent />
}
return null
}
export async function getStaticPaths(context) {
// Build paths for all `node--page` and `node--article`.
return {
paths: await drupal.getStaticPathsFromContext(
["node--page", "node--article"],
context
),
fallback: false,
}
}
export async function getStaticProps(context) {
const path = await drupal.translatePathFromContext(context)
// Get the resource type.
const type = path.jsonapi.resourceName
const params = new DrupalJsonApiParams()
// Fetch the title, path and body field for pages.
if (type === "node--page") {
params.addFields("node--page", ["title", "path", "body"])
}
// Fetch additional fields for articles.
if (type === "node--article") {
params.addFields("node--article", ["title", "path", "body", "uid"])
}
const node = await drupal.getResourceFromContext(type, context, {
params: params.getQueryObject(),
})
return {
props: {
node,
},
}
}

参考

有关获取资源和资源集合的更多示例,请参阅获取 JSON:API 资源部分。