Gatsby:从内容丰富的字段创建页面
Gatsby: Creating Pages from Contentful Fields
我在 Contentful 上的每个 post 都有一些相关联的 'categories'。例如,一个 post 可能包含:
major: "HCD"
year: "1st Year"
tools: ["R", "Python", "Wordpress"]
这些只是具有这些值的名为 major
、year
等的字段,但它们被视为单独的类别。
在网站上,它们显示如下:
我正在尝试为每个类别创建一个页面。例如,如果用户单击 Photoshop
,他们应该被带到页面 tags/photoshop
,并且应该列出所有包含该标签的 post。
幸运的是,我能够找到 this guide 来帮助我完成这项工作。但是,该指南不适用于内容丰富的数据,因此我在如何执行此操作方面遇到了一些麻烦。我已经创建了 tagsTemplate.jsx
,但我一直在创建实际页面。
例如,这是我尝试为 tools
创建页面所做的:
我的 gatsby-node.js
文件如下所示:
const path = require(`path`)
const _ = require('lodash');
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type contentfulPortfolioDescriptionTextNode implements Node {
description: String
major: String
author: String
tools: [String]
files: [ContentfulAsset]
contact: String
}
type ContentfulPortfolio implements Node {
description: contentfulPortfolioDescriptionTextNode
gallery: [ContentfulAsset]
id: ID!
name: String!
related: [ContentfulPortfolio]
slug: String!
major: String!
files: [ContentfulAsset]
author: String!
tools: [String]!
year: String!
thumbnail: ContentfulAsset
url: String
contact: String
}
`
createTypes(typeDefs)
}
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
graphql(`
{
portfolio: allContentfulPortfolio {
nodes {
slug
tools
}
}
}
`).then(({ errors, data }) => {
if (errors) {
reject(errors)
}
if (data && data.portfolio) {
const component = path.resolve("./src/templates/portfolio-item.jsx")
data.portfolio.nodes.map(({ slug }) => {
createPage({
path: `/${slug}`,
component,
context: { slug },
})
})
}
const tools = data.portfolio.nodes.tools;
const tagTemplate = path.resolve(`src/templates/tagsTemplate.js`);
let tags = [];
// Iterate through each post, putting all found tags into `tags`
tags = tags.concat(tools);
// Eliminate duplicate tags
tags = _.uniq(tags);
// Make tag pages
tags.forEach(tag => {
createPage({
path: `/tags/${_.kebabCase(tag)}/`,
component: tagTemplate,
context: {
tag
},
});
});
console.log("Created Pages For" + tags)
resolve()
})
})
}
我的tagsTemplate
现在是最小的,因为我不知道如何查询数据:
import React from 'react';
import Layout from "../layouts/Layout"
const Tags = ({ data }) => {
return (
<Layout>
<div>Tags</div>
</Layout>
);
};
export default Tags;
问题:当我访问我知道存在的标签之一的页面时(例如 photoshop
),我收到 404。为什么没有创建这些页面?
我做错了什么,我该如何解决?如何将这概括为我的三个 'categories'?
根据您在评论中所说的:
I tried console.log(tags)
but is shows it as undefined
I did that and it is just a blank space. Does that mean there is nothing in tags
at all?
您的联系人功能看起来不错,方法很好,因为您将 tools
(tags
的列表)添加到新数组中以清理它并留下唯一值(uniq
).完成后,您将遍历唯一标记并基于该数组创建页面。
也就是说,您的纸牌屋有一些弱点可能会崩溃。您的问题从这一行开始:
const tools = data.portfolio.nodes.tools;
并通过代码传播。
nodes
是一个数组,因此,要获得您应该做的任何值:
const tools = data.portfolio.nodes[0].tools;
获得第一名等等...
由于从未填充 tools
,因此其余代码不起作用。
您可以很容易地修复它循环遍历 nodes
并使用类似于以下内容的内容填充您的 tags
数组:
const toolNodes = data.portfolio.nodes;
const tagTemplate = path.resolve(`src/templates/tagsTemplate.js`);
let tags = [];
// Iterate through each post, putting all found tags into `tags`
toolNodes.map(toolNode => tags.push(toolNode.tools);
// if the fetched data is still an array you can do toolNodes.map(toolNode => tags.push(...toolNode.tools);
// Eliminate duplicate tags
tags = _.uniq(tags);
// Make tag pages
tags.forEach(tag => {
createPage({
path: `/tags/${_.kebabCase(tag)}/`,
component: tagTemplate,
context: {
tag
},
});
});
console.log("Created Pages For" + tags)
我在 Contentful 上的每个 post 都有一些相关联的 'categories'。例如,一个 post 可能包含:
major: "HCD"
year: "1st Year"
tools: ["R", "Python", "Wordpress"]
这些只是具有这些值的名为 major
、year
等的字段,但它们被视为单独的类别。
在网站上,它们显示如下:
我正在尝试为每个类别创建一个页面。例如,如果用户单击 Photoshop
,他们应该被带到页面 tags/photoshop
,并且应该列出所有包含该标签的 post。
幸运的是,我能够找到 this guide 来帮助我完成这项工作。但是,该指南不适用于内容丰富的数据,因此我在如何执行此操作方面遇到了一些麻烦。我已经创建了 tagsTemplate.jsx
,但我一直在创建实际页面。
例如,这是我尝试为 tools
创建页面所做的:
我的 gatsby-node.js
文件如下所示:
const path = require(`path`)
const _ = require('lodash');
exports.createSchemaCustomization = ({ actions }) => {
const { createTypes } = actions
const typeDefs = `
type contentfulPortfolioDescriptionTextNode implements Node {
description: String
major: String
author: String
tools: [String]
files: [ContentfulAsset]
contact: String
}
type ContentfulPortfolio implements Node {
description: contentfulPortfolioDescriptionTextNode
gallery: [ContentfulAsset]
id: ID!
name: String!
related: [ContentfulPortfolio]
slug: String!
major: String!
files: [ContentfulAsset]
author: String!
tools: [String]!
year: String!
thumbnail: ContentfulAsset
url: String
contact: String
}
`
createTypes(typeDefs)
}
exports.createPages = ({ graphql, actions }) => {
const { createPage } = actions
return new Promise((resolve, reject) => {
graphql(`
{
portfolio: allContentfulPortfolio {
nodes {
slug
tools
}
}
}
`).then(({ errors, data }) => {
if (errors) {
reject(errors)
}
if (data && data.portfolio) {
const component = path.resolve("./src/templates/portfolio-item.jsx")
data.portfolio.nodes.map(({ slug }) => {
createPage({
path: `/${slug}`,
component,
context: { slug },
})
})
}
const tools = data.portfolio.nodes.tools;
const tagTemplate = path.resolve(`src/templates/tagsTemplate.js`);
let tags = [];
// Iterate through each post, putting all found tags into `tags`
tags = tags.concat(tools);
// Eliminate duplicate tags
tags = _.uniq(tags);
// Make tag pages
tags.forEach(tag => {
createPage({
path: `/tags/${_.kebabCase(tag)}/`,
component: tagTemplate,
context: {
tag
},
});
});
console.log("Created Pages For" + tags)
resolve()
})
})
}
我的tagsTemplate
现在是最小的,因为我不知道如何查询数据:
import React from 'react';
import Layout from "../layouts/Layout"
const Tags = ({ data }) => {
return (
<Layout>
<div>Tags</div>
</Layout>
);
};
export default Tags;
问题:当我访问我知道存在的标签之一的页面时(例如 photoshop
),我收到 404。为什么没有创建这些页面?
我做错了什么,我该如何解决?如何将这概括为我的三个 'categories'?
根据您在评论中所说的:
I tried
console.log(tags)
but is shows it asundefined
I did that and it is just a blank space. Does that mean there is nothing in
tags
at all?
您的联系人功能看起来不错,方法很好,因为您将 tools
(tags
的列表)添加到新数组中以清理它并留下唯一值(uniq
).完成后,您将遍历唯一标记并基于该数组创建页面。
也就是说,您的纸牌屋有一些弱点可能会崩溃。您的问题从这一行开始:
const tools = data.portfolio.nodes.tools;
并通过代码传播。
nodes
是一个数组,因此,要获得您应该做的任何值:
const tools = data.portfolio.nodes[0].tools;
获得第一名等等...
由于从未填充 tools
,因此其余代码不起作用。
您可以很容易地修复它循环遍历 nodes
并使用类似于以下内容的内容填充您的 tags
数组:
const toolNodes = data.portfolio.nodes;
const tagTemplate = path.resolve(`src/templates/tagsTemplate.js`);
let tags = [];
// Iterate through each post, putting all found tags into `tags`
toolNodes.map(toolNode => tags.push(toolNode.tools);
// if the fetched data is still an array you can do toolNodes.map(toolNode => tags.push(...toolNode.tools);
// Eliminate duplicate tags
tags = _.uniq(tags);
// Make tag pages
tags.forEach(tag => {
createPage({
path: `/tags/${_.kebabCase(tag)}/`,
component: tagTemplate,
context: {
tag
},
});
});
console.log("Created Pages For" + tags)