以编程方式从 API 数据创建 Gatsby 页面
Programmatically create Gatsby pages from API data
这是一个与 类似的问题。
我正在寻求使用 createPage 或 createPages 以编程方式创建页面的帮助,但我遇到了问题 - 文档提供了从 markdown 文件创建页面的示例,但解释不多。
我正在使用 plugins\characters\gatsby-node.js 中的插件将 Rick & Morty API 中的数据添加到 GraphQL 数据层。如果相关,我的插件位于问题的底部。
插件确实成功添加了数据,因为我可以在 http://localhost:8000/___graphql 中看到数据,并且我已经成功地在(静态)页面中使用了数据。
我迷路的地方是我希望能够为每个单独的角色创建一个页面,为每个页面使用 url characters/<characterIdHere>
。我知道我需要向我的(主版本或插件版本...?)gatsby-node.js
文件添加一些逻辑,但这是我坚持的部分。我不知道我需要在 gatsby-node.js
文件中放入什么。 我能找到的示例都使用 json 或 markdown 文件,我想使用我已经提取的数据(从 API)到 gatsby 的数据层。我显然已经研究了几个小时并在询问之前尝试了一下,但没有任何运气。
我要创建的页面上的组件应如下所示:
const CharactersViewSingle = ({ character}) => {
return (
<div>
<Helmet>
<title>{character.name && character.name}</title>
</Helmet>
<NavBar />
<CharactersViewBox character={character} width={300} height={520} />
</div>
)
}
以上代码取自我使用create-react-app时组件返回的内容
我用来获取其他(静态)页面上的数据的 graphQL 查询(这显然反映了我想使用的数据的结构)如下所示:
export const query = graphql`
query CharactersQuery {
allCharacters(limit: 5) {
edges {
node {
id
name
status
gender
image
}
}
}
}
`
插件代码:
const axios = require("axios")
exports.sourceNodes = async ({
actions,
createNodeId,
createContentDigest,
}) => {
const { createNode } = actions
const integerList = (start, length) =>
Array.from({ length: length }, (v, k) => k + start)
const rickMortyURL = `https://rickandmortyapi.com/api/character/${integerList(
1,
493
)}`
const rickMorty = await axios.get(rickMortyURL)
const query = await axios.get(rickMortyURL)
rickMorty.data.forEach(character => {
const nodeContent = JSON.stringify(character)
const nodeMeta = {
id: character.id.toString(),
//id: createNodeId(`char-data-${character.id}`),
parent: null,
children: [],
internal: {
type: `Characters`,
content: nodeContent,
contentDigest: createContentDigest(character),
},
}
const node = Object.assign({}, character, nodeMeta)
createNode(node)
})
}
Gatsby 的 createPages
API 可能是您正在寻找的。
我用它创建了多个页面,例如 blog1、blog2、blog3 等...
同样,您可以为您的角色创建多个页面。
既然你提到你有一个 graphql 调用来让你的角色使用
const pages = await graphql(`
query CharactersQuery {
allCharacters(limit: 5) {
edges {
node {
id
name
status
gender
image
}
}
}
}
`)
上面的 graphql 调用 returns 结果是 pages.data.allCharacters.edges
现在您可以使用 foreach 迭代它们并使用 createPage 创建页面。
以下是您可能需要添加到 gatsby-node.js
文件中的完整模拟代码
const path = require('path');
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const templateOfYourCharacterPage = path.resolve(`src/templates/exampleTemplateFile.jsx`)
const pages = await graphql(`
query CharactersQuery {
allCharacters(limit: 5) {
edges {
node {
id
name
status
gender
image
}
}
}
}
`)
let characters = pages.data.allCharacters.edges;
characters.forEach(edge => {
createPage({
path: `/${edge.node.id}`,
component: templateOfYourCharacterPage,
context: {id: edge.node.uid, name: edge.node.name } // This is to pass data as props to your component.
})
})
}
这是一个与
我正在寻求使用 createPage 或 createPages 以编程方式创建页面的帮助,但我遇到了问题 - 文档提供了从 markdown 文件创建页面的示例,但解释不多。
我正在使用 plugins\characters\gatsby-node.js 中的插件将 Rick & Morty API 中的数据添加到 GraphQL 数据层。如果相关,我的插件位于问题的底部。
插件确实成功添加了数据,因为我可以在 http://localhost:8000/___graphql 中看到数据,并且我已经成功地在(静态)页面中使用了数据。
我迷路的地方是我希望能够为每个单独的角色创建一个页面,为每个页面使用 url characters/<characterIdHere>
。我知道我需要向我的(主版本或插件版本...?)gatsby-node.js
文件添加一些逻辑,但这是我坚持的部分。我不知道我需要在 gatsby-node.js
文件中放入什么。 我能找到的示例都使用 json 或 markdown 文件,我想使用我已经提取的数据(从 API)到 gatsby 的数据层。我显然已经研究了几个小时并在询问之前尝试了一下,但没有任何运气。
我要创建的页面上的组件应如下所示:
const CharactersViewSingle = ({ character}) => {
return (
<div>
<Helmet>
<title>{character.name && character.name}</title>
</Helmet>
<NavBar />
<CharactersViewBox character={character} width={300} height={520} />
</div>
)
}
以上代码取自我使用create-react-app时组件返回的内容
我用来获取其他(静态)页面上的数据的 graphQL 查询(这显然反映了我想使用的数据的结构)如下所示:
export const query = graphql`
query CharactersQuery {
allCharacters(limit: 5) {
edges {
node {
id
name
status
gender
image
}
}
}
}
`
插件代码:
const axios = require("axios")
exports.sourceNodes = async ({
actions,
createNodeId,
createContentDigest,
}) => {
const { createNode } = actions
const integerList = (start, length) =>
Array.from({ length: length }, (v, k) => k + start)
const rickMortyURL = `https://rickandmortyapi.com/api/character/${integerList(
1,
493
)}`
const rickMorty = await axios.get(rickMortyURL)
const query = await axios.get(rickMortyURL)
rickMorty.data.forEach(character => {
const nodeContent = JSON.stringify(character)
const nodeMeta = {
id: character.id.toString(),
//id: createNodeId(`char-data-${character.id}`),
parent: null,
children: [],
internal: {
type: `Characters`,
content: nodeContent,
contentDigest: createContentDigest(character),
},
}
const node = Object.assign({}, character, nodeMeta)
createNode(node)
})
}
Gatsby 的 createPages
API 可能是您正在寻找的。
我用它创建了多个页面,例如 blog1、blog2、blog3 等... 同样,您可以为您的角色创建多个页面。
既然你提到你有一个 graphql 调用来让你的角色使用
const pages = await graphql(`
query CharactersQuery {
allCharacters(limit: 5) {
edges {
node {
id
name
status
gender
image
}
}
}
}
`)
上面的 graphql 调用 returns 结果是 pages.data.allCharacters.edges
现在您可以使用 foreach 迭代它们并使用 createPage 创建页面。
以下是您可能需要添加到 gatsby-node.js
文件中的完整模拟代码
const path = require('path');
exports.createPages = async ({ graphql, actions }) => {
const { createPage } = actions
const templateOfYourCharacterPage = path.resolve(`src/templates/exampleTemplateFile.jsx`)
const pages = await graphql(`
query CharactersQuery {
allCharacters(limit: 5) {
edges {
node {
id
name
status
gender
image
}
}
}
}
`)
let characters = pages.data.allCharacters.edges;
characters.forEach(edge => {
createPage({
path: `/${edge.node.id}`,
component: templateOfYourCharacterPage,
context: {id: edge.node.uid, name: edge.node.name } // This is to pass data as props to your component.
})
})
}