iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 14
0
Modern Web

雖然你不是木村拓哉,但它也可以讓你變很行 - Gatsby.js系列 第 14

[Day 14] - 建置第一個 Blog - 文章內頁 ( 上 )

  • 分享至 

  • xImage
  •  

[Day 14] - 建置第一個 Blog - 文章內頁

在前一篇文章中,我們建立了一個還不錯的列表頁,但我們絕對不滿足於此,今天,我們要用更聰明的方式來建立頁面,話不多說,就讓我們開始吧!

為頁面創建 Slug

為了將我們的 MD 做成頁面,我們會需要用到兩個 API ,分別為 onCreateNode 與 createPages,

筆者會將這兩隻 API 的文件放到參考資料中,有興趣的讀者可以自行閱讀。

為了使用 Gatsby 提供的 API,我們需要在根目錄上先創建一隻 gatsby-node.js 檔案,並在檔案中加入以下程式碼。

exports.onCreateNode = ({ node }) => {
  console.log(node.internal.type)
}

完成後,應該會如下圖所示。

https://ithelp.ithome.com.tw/upload/images/20200929/20109495wXWwaVyBur.png

這隻 API 在我們藉由 gatsby develop 來開啟開發伺服器時,在伺服器的初始化過程中,會被調用到,因此,我們也能在終端機中看見一些 Console,

https://ithelp.ithome.com.tw/upload/images/20200929/20109495ee15Ts5Cee.png

接下來,我們要在 onCreateNode 這隻 API 被觸發時,其觸發的類型等於 MarkdownRemark 時,來添加 Slug 到我們的 MD 頁面。

所以我們來調整一下 gatsby-node.js 裡的程式碼

exports.onCreateNode = ({ node }) => {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(node.internal.type)
  }
}

而 Slug 的作用是作為當我們輸入特定路由時,系統知道要去哪一隻檔案中撈取資料。

像是昨天我們創建在 src/pages 下的 first-article.md 網址就應該呈現為,/first-article/,但我們要怎麼獲得檔案的名稱呢?

我們就需要去找 MarkdownRemark 的父層 File,File 裡頭包含了我們所有想到的資料,所以我們再次改動程式碼來符合我們的需求

exports.onCreateNode = ({ node, getNode }) => {
  if (node.internal.type === `MarkdownRemark`) {
    const fileNode = getNode(node.parent)
    console.log(`\n`, fileNode.relativePath)
  }
}

這邊有用到 Gatsby 的一個 API getNode,同樣地,我們放在參考資料中。

接著,我們再來重啟開發者伺服器來確認一下結果吧。

https://ithelp.ithome.com.tw/upload/images/20200929/201094952ywxlLG7dh.png

現在我們成功的找到了檔案的路徑了,能藉由檔名來作為 Slug
剛好,先前我們安裝的套件中 gatsby-source-filesystem 有提供這樣的 Method 方便我們調用,於是我們再來改寫程式碼吧!

我們先引入 createFilePath,這個函式能幫我們做到找尋父文件及建立 Slug

const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode }) => {
  if (node.internal.type === `MarkdownRemark`) {
    console.log(createFilePath({ node, getNode, basePath: `pages` }))
  }
}

我們將程式碼改為上圖後,再次重啟開發伺服器吧!

https://ithelp.ithome.com.tw/upload/images/20200929/20109495nShPoA2HgI.png

應該就能看到 Console 輸出了我們所預期的結果,而最後一步,我們就是要將這資料塞到 GraphQL 的對應節點中,這邊我們會用到 createNodeField 這隻 API 來把我們上面的資料放到對應的位置上。

所以我們先把 createNodeField 從 actions 解構出來,接著命名一個變數為 slug 並 assing 給他我們 createFilePath 回傳的值 ( /first-article/ ),最後用 createNodeField 來把值塞進去。

const { createFilePath } = require(`gatsby-source-filesystem`)

exports.onCreateNode = ({ node, getNode, actions }) => {
  const { createNodeField } = actions
  if (node.internal.type === `MarkdownRemark`) {
    const slug = createFilePath({ node, getNode, basePath: `pages` })
    createNodeField({
      node,
      name: `slug`,
      value: slug,
    })
  }
}

記得將 gatsby-node.js 的程式碼替換成上圖,然後重啟開發伺服器後,打開 GraphiQL 吧! ( http://localhost:8000/___graphql )

將 allMarkdownRemark 展開後,選取下方的 fields slug ,接著用快捷鍵 Ctrl + enter 來看看 Query 的結果吧

https://ithelp.ithome.com.tw/upload/images/20200929/20109495SRoswQmzUs.png

我們成功的撈出了剛剛建立的 Slug !!!

https://ithelp.ithome.com.tw/upload/images/20200929/20109495765LVorPKl.png

明天我們就會藉由這些資訊來 Query,
然後將資料放到我們預先處理好的頁面中,
我們又離完整的 Blogs 更近一步了唷!

中秋連假一定要存稿、一定要存稿、一定要存稿

參考資料

createNode
createPages
getNode
createNodeField


上一篇
[Day 13] - 建置第一個 Blog - 文章列表
下一篇
[Day 15] - 建置第一個 Blog - 文章內頁 ( 下 )
系列文
雖然你不是木村拓哉,但它也可以讓你變很行 - Gatsby.js30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言