快轉到主要內容

Hugo如何從json檔讀取資料並渲染HTML網頁

資訊科技 Hugo網站架設 Hugo
🗓️ 民國113年 甲辰年
✍ 切換正體/簡體字
目錄

Rendering Hugo HTML webpages from json data.

你有一份csv結構化儲存的資料,想要做成表格展示在網頁上嗎?

想要使用單個json檔案,生成多篇文章嗎?

想要用程式化的方法,從yaml檔案生成多個頁面嗎?

想要製作key-value為主的網頁字串翻譯方式嗎?

那麼你可以使用Hugo的「Data功能!它可以讀取Hugo網站下的文字檔案,讀取內容並按照你的意思渲染網頁。

資料檔格式可以是json、yaml、toml或csv,我用json舉例。

1. Hugo的Data儲存位置
#

參考 Data templates - Hugo

關於資料檔儲存的位置,因為函數路徑的限制,所以只能放在網站根目錄下的data目錄。

Page Bundle的方式有點複雜。

例如我在網頁根目錄的data/放一個mydata.json,他的引用路徑就會變成site.Data.mydata

如果有多層目錄,就將其轉換成點,例如data/posts/mydata.json會變成site.Data.posts.mydata

data.json檔案內容是這樣的。我希望將其渲染成HTML表格。

//竇唯的歷年專輯,注意Hugo渲染json不允許註解
[
{
"name" : "黑夢",
"year": 1994,
"label": "魔岩唱片"
},
{
"name" : "豔陽天",
"year": 1995,
"label": "魔岩唱片"
},
{
"name" : "山河水",
"year": 1998,
"label": "魔岩唱片"
}
]

如果你不喜歡Hugo的i18n網頁處理模式的話,你還可以準備一個mydatatranslation.json檔案,用於翻譯網頁字串:

{
"name" : "唱片名稱",
"year": "年份",
"label": "唱片廠牌"
}

2. 撰寫讀取資料檔的shortcode
#

讀取json不論是partial還是shorcode都能做到。

partial是內嵌在主題裡面的,跟著全域網頁一起跑,例如我之前做過的 Hugo天干地支紀年法

shortcode則是能在文章markdown隨時引用,那麼我這裡就用shortcode程式吧。

  1. 在網站根目錄layouts/shortcodes/新增一個檔案addtable.html

  2. 填入以下內容。我允許使用者在引用Shortcode時候傳變數進來,再按照引數內容變化。


{{ $targetfile := index .Params 0 }}

<!--讀取Shortcode傳入的變數1,指定給targetfile,再將完整檔案路徑指定給變數inputfile-->

{{ $inputlist := index site.Data $targetfile }}

<!--讀取Shortcode傳入的變數2,指定給showdescription-->

{{ $showlabel := index .Params 1 }}


<!--讀取翻譯檔案-->

{{ $translation := index site.Data.mydatatranslation }}


<!--If判斷式-->

{{ if eq $showlabel "showlabel"  }}


<!--表格-->
<table>
  <thead>
    <tr>
    <!--表格頂層,讀取mytranslationlist的鍵值,填入翻譯-->
    {{ with $translation }}
      <th> index .name </th>
      <th> index .year </th>
      <th> index. label </th>
    </tr>
    {{ end }}
  </thead>
  <tbody>
  <!--因為表格最外層是陣列,要用range走訪-->
    {{ range $inputfile }}
    <tr>
     <!--如果要讀取的鍵值有空格,就用這個方法讀取-->
      <td>{{ index . "name" }}</td>
      <td>{{ index .year }}</td>
      <td>{{ index .label }}</td>
    </tr>
    {{ end }}
  </tbody>
</table>

 {{ else }}

 <table>
  <thead>
    <tr>
      <th> 名稱 </th>
      <th> 年份 </th>
    </tr>
  </thead>
  <tbody>
    {{ range $inputfile }}
    <tr>
      <td>{{ index . "name" }}</td>
      <td>{{ .year }}</td>
    </tr>
    {{ end }}
  </tbody>
</table>


{{ end }}

目前我不知道怎麼讀取巢狀陣列:P

所以第一層以下的json都是物件式的鍵值。

3. 在文章中引用shortcode
#

makrdown中引用的shorcode要這樣寫,引用addtabel.html,並傳入二個參數。

{{< addtable "mydata" "showdescription" .  >}}

參考資料
#

相關文章

讓Hugo網頁顯示中文日期,附贈民國、天干地支紀年的顯示方法
資訊科技 Hugo網站架設 Hugo
VSCode + Front Matter CMS,打造Hugo靜態網站管理後台
資訊科技 Hugo網站架設 Hugo Visual Studio Code
自訂Hugo的RSS訂閱,過濾特定文章不讓其出現在RSS列表
資訊科技 Hugo網站架設 Hugo RSS Feed

留言板

此處提供二種留言板。點選按鈕,選擇您覺得方便的留言板。要討論程式碼請用Giscus,匿名討論請用Disqus。

這是Giscus留言板,需要Github帳號才能留言。支援markdown語法,若要上傳圖片請貼Imgur連結。您的留言會在Github Discussions向所有人公開。

這是Disqus留言板,您可能會看到Disqus強制投放的廣告。有時留言可能會被系統判定需審核,導致延遲顯示,請見諒。