DEV Community

Cover image for 製作一個 Hugo + Tailwind CSS 初始檔
Let's Write
Let's Write

Posted on • Updated on • Originally published at letswrite.tw

製作一個 Hugo + Tailwind CSS 初始檔

本篇要解決的問題

之前看了 Hugo 的教學,覺得這套 SSG 的工具不錯用,再加上最近租的主機要到期了,一些文章數很少的站,或是最近準備再寫幾篇文章的站,打算從 WordPress 脫離到 Hugo 上,並把產生出的靜態檔直接放在 GitHub Pages,做出一個免費的站。

因為有二個站想搬,就想先做一個 Hugo + Tailwind CSS 的初始檔出來,讓二個站 clone 初始檔後直接改樣式就可以上線。

結果不做不知道,一做不得了,好多的眉眉角角都是教學裡沒有的,得去從茫茫的文件裡去尋找,這篇就是把在做初始檔時遇到的這些問題,相關的解決方式給整理起來,相信是跟 August 一樣剛踏入 Hugo 宇宙的朋友們也會遇到的,希望可以減少大家踩坑時間。

最後也會附上初始檔的 GitHub 專案連結。


初始檔:安裝、開發、產靜態檔

這邊先寫一下怎麼使用這個初始檔。

先進到專案的頁面下載整包專案:https://github.com/letswritetw/letswrite-hugo-tailwindcss-init

下載前請點擊星星給 Let’s Write 一個鼓勵,這個初始檔真的做了好幾天。

確定你的本機有安裝 Node.js,沒有的話請先安裝,接著繼續安裝 Yarn 的話會更好。

專案裡開啟終端機,輸入:

$ npm install
$ yarn
Enter fullscreen mode Exit fullscreen mode

package.json 都寫好了,執行上面的 Command 就會安裝 Tailwind CSS。

要開發、要產出靜態檔也都寫好了,一樣用 Command 來執行。

開發

$ npm run serve
或
$ yarn serve
Enter fullscreen mode Exit fullscreen mode

產靜態檔

$ npm run build
或
$ yarn build
Enter fullscreen mode Exit fullscreen mode

為了放在 GitHub Pages 上,所以產出的靜態檔會是「docs」這個資料夾。


config

config 檔,因為想讓自己習慣 YAML,所以檔案為 config.yml。

Sitemap

文件:Sitemap Templates

config 檔可以設定輸出 Sitemap 檔,不過之前上 SEO 的講座時,其實有一種說法是:如果導覽列夠健全,Sitemap 就沒這麼重要。但說法是說法,既然可以自動產生了,就還是建一建。

sitemap:
  changefreq: weekly
  filename: sitemap.xml
  priority: 1.0
Enter fullscreen mode Exit fullscreen mode

changefreq 是指頁面的更新頻率,共有以下的值可以寫:

always, hourly, daily, weekly, monthly, yearly, never
Enter fullscreen mode Exit fullscreen mode

當然,大家常常都馬寫 always,priority 都馬寫 1.0,這就是為什麼 Sitemap的重要程度會愈來愈低吧,就跟以前塞 meta keywords 一樣。

寫在 config 檔是全站共用的,如果想要有單獨的頁面不一樣,就寫在頁面檔的 Front Matter 就好。

Google Analytics

config 可以寫入 GA 的追蹤 ID,再加上內建的模版,Hugo 就會埋入 GA 追蹤碼。

config

googleAnalytics: GA 追蹤碼 ID
Enter fullscreen mode Exit fullscreen mode

在要埋入的地方加入以下 HTML,本專案是加在 layouts/partials/head.html 裡:

{{ template "_internal/google_analytics.html" . }}
Enter fullscreen mode Exit fullscreen mode

因為 2023 年 7 月後,Google 就要全面只能用 GA4,因此這邊裝的是 GA4 的 HTML。

但如果要放多個 GA 呢?無解,文件上沒有寫。

如果要放多個,建議直接在 head 裡手動放 Google Tag Manager 的代碼,改由 GTM 來塞 GA 追蹤碼。

客製參數

Let’s Write 製作的這份初始檔,有二個客製的參數是寫在 config 裡的:

params:
  mainColor: '#42A6F7'
  favicon: 這邊填寫 favicon 的圖檔路徑
Enter fullscreen mode Exit fullscreen mode

mainColor 會用在 theme-color、msapplication-TileColor 這二個 meta 上,一個是手機的瀏覽器功能條的顏色,一個是存成 Windows App 時會有的顏色,其實不太重要,但要注重細節的話就是也寫一下,把自己品牌的主色系碼給填上去。

第二個就是 favicon 的路徑。


head 檔

layouts/partials/head.html 這個檔,是頁面

裡的內容。在這裡踩到的坑有以下幾點。

Open Graph

文件:Open Graph

Open Graph 主要是

裡放社群分享時的卡片資訊,一般是用在 FB、LINE,Hugo 在 Front Matter 裡可以設定標題、描述、配圖、日期、影音、分類。

Let’s Write 的初始檔分別為以下:

title: 標題
description: 描述
cover: 配圖
date: 日期
categories:
    - 分類
videos:
    - 影片網址
Enter fullscreen mode Exit fullscreen mode

categories 影響的是頁面裡的 see also,中文可以翻作「你可能有興趣」、「看過這篇的人也看過」之類的。文件裡用的是 series,但這邊實作 categories 也有同樣效果。

各頁的 Front Matter 設好後,在模版檔上要放入 Open Graph 的模版,這個是內建的模版:

{{ template "_internal/opengraph.html" . }}
Enter fullscreen mode Exit fullscreen mode

引用 CSS、JS 檔

文件:Hugo Pipes IntroductionJavaScript Building

引用 CSS、JS 這段真的是踩了一個坑,主要是雖然 Hugo 開發時,檔案一存檔後本機的 Demo 網址就會即時更新,但 CSS、JS 是有快取的,不清快取即便重整也會一直看到舊的 CSS 跟 JS。

後來看了文件,才知道 Hugo 有設定了 fingerprint 的功能,可以讓引用的 CSS、JS 檔的檔名每次都不一樣。

將 CSS 檔放進 assets/css/ 的資料夾中,JS 檔放進 assets/js/ 的資料夾中。主要是放 assets 這個資料夾裡的檔案才能用 resource 的方式去抓取。

<!-- 引用 CSS -->
{{ $tailwind := resources.Get "css/tailwind.min.css" | fingerprint }}
<link rel="stylesheet" href="{{ $tailwind.Permalink }}">

<!-- 引用 JS -->
{{ $main := resources.Get "js/main.js" | js.Build "main.js" | minify | fingerprint }}
<script src="{{ $main.Permalink }}"></script>
Enter fullscreen mode Exit fullscreen mode

CSS 的部份,Hugo 可以直接編譯 SASS/SCSS,但因為本初始檔用的是 Tailwind CSS,因此就加上 fingerprint 讓檔名補上亂數就行。

JS 的部份,Hugo 可以編譯 ES6+ 耶~ 還可以壓縮檔案,所以這邊就是寫編譯 + 壓縮 + 加亂數。


Schema 結構化資料

這塊是 SEO 用的,完整的文件請看 Google:瞭解結構化資料的運作方式

layouts/partials/schema.html 裡有放了一個基本的「標誌」:

<script type="application/ld+json">
  {
    "@context": "https://www.schema.org",
    "@type": "Organization",
    "name": "{{ .Site.Title }}",
    "url": "{{ .Site.BaseURL }}",
    "logo": "{{ .Site.Params.favicon }}"
  }
</script>
Enter fullscreen mode Exit fullscreen mode

然後在 baseof.html 上用 partial 的引用:

{{ partial "schema.html" . }}
Enter fullscreen mode Exit fullscreen mode

這種作法是參考這篇:Adding Structured Data to your Hugo site

可是很奇怪的是,在 Hugo 的文件裡,內建模版裡原本就有 Schema 的:

{{ template "_internal/schema.html" . }}
Enter fullscreen mode Exit fullscreen mode

只是文件上沒有說明到底要怎麼使用,要加什麼參數才會有,August 直接引用後是沒有吐出什麼程式碼出來,因此才改用 partial 的方式。

知道內建模版關於 Schema 的朋友歡迎留言提供~


content 檔案架構

content 裡放的是每個文章的頁面,檔案裡的架構是這樣:

content
├── post
│   ├── demo1
│   │   ├── cover.png
│   │   └── index.md
│   ├── demo2
│   │   ├── cover.png
│   │   └── index.md
│   └── index.md(posts 的列表首頁)
└── index.md(網站首頁)
Enter fullscreen mode Exit fullscreen mode

像 demo1,每一篇文章都是收在一個資料夾裡,裡面有 index.md 是內文,還有一個圖檔是配圖。

都放在同一個資料夾裡,要抓配圖的方式就是:

{{ $image := .Resources.GetMatch "xxx.jpg" }}
Enter fullscreen mode Exit fullscreen mode

另外也可以統一將所有圖檔放進一個資料夾裡,這個資料夾必須位在 assets 裡,像 assets/images/。要抓配圖的方式就是:

{{ $image := resources.Get "images/xxx.jpg" }}
Enter fullscreen mode Exit fullscreen mode

但這個方式,August 不管怎麼試就是失敗,一直抓不到圖檔的寬高,所以本初始檔是用第一種圖檔跟文章都放在同一個資料夾的方式。

圖檔也可以是外面的圖庫,抓配圖的方式就是:

{{ $image := resources.GetRemote "https://xxx.xxx/xxx.png" }}
Enter fullscreen mode Exit fullscreen mode

抓了配圖後,可以抓到圖檔的路徑、寬度、高度,範例如下:

{{ $image := .Resources.GetMatch "xxx.jpg" }}
{{ with $image }}
  <img src="{{ .RelPermalink }}" width="{{ .Width }}" height="{{ .Height }}">
{{ end }}
Enter fullscreen mode Exit fullscreen mode

圖檔抓文章連結、裁切

layouts/partials/cover.html 這個檔有做圖檔的引用、裁切,主要是處理文章配圖。

Hugo 除了引用圖檔,也可以設定一個圖片尺寸,會自動將圖裁成設定的寬。

這邊也踩了一個坑,主要是加入文章連結的部份,上面的範例 code,用了 {{ .RelPermalink }} 去抓圖片路徑,不幸的是,文章連結這個變數也是用 RelPermalink,解決方式就是先將文章連結存成一個變數。

整合抓文章連結、裁切圖片,範例的程式碼可以改成以下:

{{ $Uri := .RelPermalink }}
{{ $Image := .Resources.GetMatch (print .Params.cover) }}
{{ $ImageResize := $Image.Resize "768x" }}
{{ with $Image }}
  <div>
    <a href="{{ $Uri }}">
      <img
        src="{{ $ImageResize.RelPermalink }}" alt="{{ .Title }}"
        width="{{ $ImageResize.Width }}" height="{{ $ImageResize.Height }}">
        </a>
  </div>
{{ end }}
Enter fullscreen mode Exit fullscreen mode

完整的說明可以看文件:Image Processing


未完待續

目前 August 完成的是初始的檔案,But,是還沒實際使用過的,之後會開始拿這份檔實際把手上的小站搬家看看,如果操作的過程中覺得目前架構或設計有不順的,就會一併修改。

初始檔 GitHub 專案的連結在這,取用前麻煩點個星星,或分享本篇文章,你的小小動作對本站都是大大的鼓勵:

https://github.com/letswritetw/letswrite-hugo-tailwindcss-init

Top comments (0)