在前天的文章有提到,我希望將網站分為兩種不同的頁面類型,一種是文章、一種是筆記,然後可能會有不同的佈局,今天就來研究如何在 Gatsby 實作吧!
首先,第一個問題是「能不能在 GraphQL Query 中,將兩種類型分開?」,目前的 query 如下:
const result = await graphql(`
query {
allMdx(filter: { fields: { visibility: { eq: "public" } } }) {
edges {
node {
fields {
slug
fileName
title
visibility
excerpt
}
frontmatter {
tags
title
date
aliases
}
excerpt
rawBody
body
}
}
}
tags: allMdx(limit: 2000) {
group(field: frontmatter___tags) {
fieldValue
}
}
}
`)
const allNotes = _.get(result, `data.allMdx.edges`)
那我只要在 query 用不同的 key 進行不同的 query,且用路徑作為 filter 即可:
const result = await graphql(`
query {
articles: allMdx(
filter: { fileAbsolutePath: {regex: "/_content/articles/"} }
) { ... }
notes: allMdx(
filter: { fileAbsolutePath: {regex: "/_content/notes/"} }
) { ... }
tags: allMdx(limit: 2000) {
group(field: frontmatter___tags) {
fieldValue
}
}
}
`)
const allArticles = _.get(result, `data.notes.allMdx.edges`)
const allNotes = _.get(result, `data.notes.allMdx.edges`)
接著用兩個不同的迴圈去遍歷這些節點,然後為此建立不同 component 樣板的頁面即可:
// Create pages for all notes.
for (let i = 0; i < result.data.notes.allMdx.edges.length; i++) {
const node = result.data.allMdx.edges[i].node
const title = node.fields.title || node.frontmatter.title
// ....
createPage({
path: `/notes/${node.fields.slug}`,
component: path.resolve(`./src/templates/note.jsx`),
context: {
title: title,
slug: node.fields.slug,
refersTo: refersTo[title] || [],
referredBy: referredBy[title] || [],
linkedNotes: linkedNotes
},
})
}
// Create pages for all articles.
for (let i = 0; i < result.data.notes.allMdx.edges.length; i++) {
const node = result.data.allMdx.edges[i].node
const title = node.fields.title || node.frontmatter.title
// ....
createPage({
path: `/articles/${node.fields.slug}`,
component: path.resolve(`./src/templates/articles.jsx`),
context: {
title: title,
slug: node.fields.slug,
refersTo: refersTo[title] || [],
referredBy: referredBy[title] || [],
linkedNotes: linkedNotes
},
})
}