前一篇文章,我們成功的建立了環境,今天我們要來添加一些靜態資料到專案中,並用這些資料來創建一些頁面。
首先,我們在 Gatsby-theme-events 目錄下建立一個 data 資料夾,並在資料夾中新增一支 YAML 檔,名稱為 events.yml,裡面放一些示範用的數據。
- name: ModernWeb 2020
location: online
start_date: 2020-10-12
end_date: 2020-10-16
url: https://modernweb.tw/
- name: JSDC 2020
location: online
start_date: 2020-10-17
end_date: 2020-10-17
url: https://2020.jsdc.tw/
YAML 是一種可讀性高,用來表達資料序列化的格式。其意思表示 “Yet Another Markup Language” ( 仍是一種標記語言 )。YAML - Wiki
這時你的資料夾結構應該會如下圖所示
而我們要讀取剛剛新增的 YAML 檔的資料,必須有幾支套件來協助我們,
分別為 gatsby-source-filesystem 與 gatsby-transformer-yaml,所以我們在終端機中輸入以下指令
yarn workspace gatsby-theme-events add gatsby-source-filesystem gatsby-transformer-yaml
安裝完後,我們要為 gatsby-theme-events 添加一些設定,所以我們需要建立一支 gatsby-config.js 檔,並在裡面匯出我們剛剛安裝的外掛,程式碼就如下面範例所示。
module.exports = {
plugins: [
{
resolve: "gatsby-source-filesystem",
options: {
path: "data",
},
},
{
resolve: "gatsby-transformer-yaml",
options: {
typeName: "Event",
},
},
],
}
新增完後,我們開啟 gatsby-theme-events 工作區的開發伺服器
yarn workspace gatsby-theme-events develop
接著,我們輸入 http://localhost:8000/__graphql 來看看是否有成功讀取剛剛新增的資料,進入到畫面後,我們選取 allEvent > nodes > name 後 ( 如下圖 ),再用快捷鍵 Ctrl + Enter 來 Query 看看結果是否是我們所預期的。
這時,讀者們的畫面應該要如下圖般,撈出剛剛我們新增的資料。
我們完成上面的步驟後,接下來,我們在 gatsby-theme-events 工作區中建立 Gatsby-node.js 檔,並在裡面新增以下程式碼
const fs = require("fs")
exports.onPreBootstrap = ({ reporter }) => {
const contentPath = "data"
if (!fs.existsSync(contentPath)) {
reporter.info(`creating the ${contentPath} directory`)
fs.mkdirSync(contentPath)
}
}
這段程式碼我們引入了 nodeJS 的 File System,來幫助我們確認到 data 資料夾是否存在,因為我們安裝的套件 gatsby-source-filesystem 在主題啟動時會去讀取 data 資料夾,而如果它並不存在的話,會引發錯誤,所以為了預防此種情境發生,我們就需要用 onPreBootstrap API 來檢查,如果發現沒有 data 資料夾,就直接創建一個。
我們要用資料來動態的建立頁面,需要做到以下幾點
接下來我們會用 createTypes 來創建我們自定義的 Event 類型,並用 @dontInfer 來明確定義,讓 Gatsby 不要對這個類型做推斷,接著將 name、location、startDate、endDate、url 等自訂的欄位創建資料,並且多創立一個 slug ,我們會用它來做路由。
於是我們在 gatsby-node.js 中,新增以下這段
exports.sourceNodes = ({ actions }) => {
actions.createTypes(`
type Event implements Node @dontInfer {
id: ID!
name: String!
location: String!
startDate: Date! @dateformat @proxy(from: "start_date")
endDate: Date! @dateformat @proxy(from: "end_date")
url: String!
slug: String!
}
`)
}
若對這邊概念有點模糊的讀者,可以試著閱讀 Gatsby.js - createTypes
接著,我們要使用 createResolvers API 與 正規表示法 ( Regular Expression ) 來為 Slug 做一些處理,例如統一小寫、特殊符號過濾等等,經過處理後,再將處理後的值回傳並新增到我們自定義的 Event 類型的欄位中。
createResolvers 中,我們先定義根目錄為 / ,並新增一個函式來幫助我們做 slug 的解析,最後在 Event 類型中新增它 ( Slug )
exports.createResolvers = ({ createResolvers }) => {
const basePath = "/"
const slugify = str => {
const slug = str
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/(^-|-$)+/g, "")
return `/${basePath}/${slug}`.replace(/\/\/+/g, "/")
}
createResolvers({
Event: {
slug: {
resolve: source => slugify(source.name),
},
},
})
}
同樣的,我們將以上程式碼新增到 gatsby-node.js 中,接著再重啟開發伺服器後,我們重新 Query 看看資料是否如我們預期中的運行。
query MyQuery {
allEvent {
nodes {
name
slug
startDate(formatString: "MMMM DD YYYY")
endDate(formatString: "MMMM DD YYYY")
}
}
}
經由以上的 Query ,我們能得出以下的結果
各位讀者可以看到,紅框處就是我們上面程式碼正確執行的結果,也就是我們明天動態建立頁面時,每個頁面的路由。
正規表示法常用來作字串的搜尋、替換、過濾等,是非常好用的工具,有興趣的讀者可以搜尋看看唷。正規表示法 - Wiki
今天的內容可能會對一些讀者來說比較吃力,若感覺較吃力的讀者可以先照著範例往下做,等我們的主題建置都完成後,再回頭來看看,可能會有不同的感受唷!