HTML 的 <head> 會載入 CSS,也是各 Template 都會重複使用之處,可將其抽成 Partial 方便維護。
Version
Hugo 0.148.0
SCSS
assets/scss/main.scss
@use 'vars';
@use 'baseof';
@use 'home';
@use 'single';
@use 'list';
@use '_partials/header';
@use '_partials/footer';
@use 'page/about';
- 使用
@use引用其他 SCSS,本身不寫任何 style
CSS Partial
layouts/_partials/css.html
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{{ .Site.Title }}</title>
<link rel="icon" href="/favicon.ico" />
{{ with resources.Get "scss/main.scss" }}
{{ $opts := dict
"enableSourceMap" hugo.IsDevelopment
"outputStyle" (cond hugo.IsDevelopment "expanded" "compressed")
"transpiler" "dartsass"
"targetPath" "css/main.css"
}}
{{ with . | toCSS $opts }}
{{ if hugo.IsDevelopment }}
<link rel="stylesheet" href="{{ .RelPermalink }}" />
{{ else }}
{{ with . | fingerprint }}
<link
rel="stylesheet"
href="{{ .RelPermalink }}"
integrity="{{ .Data.Integrity }}"
crossorigin="anonymous" />
{{ end }}
{{ end }}
{{ end }}
{{ end }}
- 負責載入 CSS
Line 3
<title>{{ .Site.Title }}</title>
Site.Title:讀取titlesite variable
Line 4
<link rel="icon" href="/favicon.ico" />
- 引用在
static目錄下的favicon.ico
Line 5
{{ with resources.Get "scss/main.scss" }}
{{ end }}
resources.Get():從assets目錄取得main.scsswith():若scss/main.scss存在,將目前 context切到所回傳物件繼續 pipe
Line 6
{{ $opts := dict
"enableSourceMap" hugo.IsDevelopment
"outputStyle" (cond hugo.IsDevelopment "expanded" "compressed")
"transpiler" "dartsass"
"targetPath" "css/main.css"
}}
dict():整理toCSS()所需 map 參數enableSourceMap:開發模式時true,生產模式時則falseoutputStyle:開發模式時不壓縮,生產模式時壓縮transpiler:指定使用 Dart Sass,而非內建的 LibSasstargetPath:最終產出為css/main.css
Line 12
{{ with . | toCSS $opts }}
{{ end }}
toCSS():將目前 context傳入toCSS $opts目前 context是scss/main.scss物件toCSS $opts為 partial function,因此可將.傳入
with():若toCSS()成功,則將目前 context切到回傳物件繼續 pipe
Line 13
{{ if hugo.IsDevelopment }}
<link rel="stylesheet" href="{{ .RelPermalink }}" />
開發模式 下處理 CSS:
RelPermalink:直接從目前 context取得其相對路徑目前 context是toCSS()回傳物件
Line 15
{{ else }}
{{ with . | fingerprint }}
<link
rel="stylesheet"
href="{{ .RelPermalink }}"
integrity="{{ .Data.Integrity }}"
crossorigin="anonymous" />
{{ end }}
{{ end }}
生產模式 下處理 CSS:
fingerprint():將 CSS 檔名加上 hash,避免被連覽器 cache- 目前
context是toCSS()回傳物件
- 目前
with():若fingerprint()成功,則將目前 context切到回傳物件繼續 pipeRelPermalink:直接從目前 context取得其相對路徑Data.Integrity:提供 SRI,用來讓瀏覽器驗證資源內容是否被竄改,需搭配crossorigin="anonymous"目前 context是fingerprint()回傳物件
Baseof Template
layouts/baseof.html
<!doctype html>
<html lang="en">
<head>
{{ partial "css.html" . }}
</head>
<body>
{{ block "main" . }}{{ end }}
{{ partial "js.html" . }}
</body>
</html>
- 所有 template 基礎的
baseof.html
Line 3
<head>
{{ partial "css.html" . }}
</head>
- 在
<head>內引用csspartial
Conclusion
- CSS 要處理的東西看似簡單,這原本都要靠 Gulp、Webpack、Vite 之類工具處理,但這些 Hugo 都已經內建,只需 Pipe 即可,可將這些處理過程整合在
cssPartial 內 - 之所以要朝狀使用
with(),因為每個 Function 執行會成功或失敗,只有成功後才會將目前 Context切到回傳物件繼續 Pipe - 此段處理 CSS 流程摘自 Hugo 官網,極具參考價值,是非常優秀的 Go template 寫法