Skip to main content

在 Hugo 中重新命名資產名稱

重命名資產,避免使用預設的資產名稱,讓你的網站看起來更專業。有兩種不同情況對應兩種不同方案。

Template Resources

模板類型的資源,如文字 template.css.tmpl

https://discourse.gohugo.io/t/minification-behavior-for-template-output/57292/3

{{ with resources.Get "template.css.tmpl" }}
{{ with .Content | resources.FromString "css/main.css" }}
{{ with . | resources.ExecuteAsTemplate "css/main.css" $ }}
{{ with . | resources.Minify }}
<link rel="stylesheet" href="{{ .RelPermalink }}">
{{ end }}
{{ end }}
{{ end }}
{{ end }}

圖像資源

Hugo 的 resize/hash 會讓資源變成超長一串而且完全看不懂這個資源是哪種版本,難讀至極,比如 [FILENAME]_hu_be179265bd5fce19.ext,完全不知道這是用於什麼的版本,是縮圖還是什麼東西。

唯一的方案是 resources.Copy 解決,以 responsive images 為例,目標是生成 [FILENAME]-[XXX]px_[HASH].webp 格式的圖片,代碼如下:

{{/* Optimizes an image and returns desktop and mobile resized versions alongside the original.
@param imgObj {resource.Resources}: The image resource object.
@param desktopWidth {int}: Optional. The target width for the desktop version.
@param mobileWidth {int}: Optional. The target width for the mobile version.
@returns {map} A dict of processed Resources object. `imgObj` (original), `imgDesktop`, and `imgMobile`.
*/}}

{{- $imgObj := .imgObj -}}
{{- $desktopWidth := .desktopWidth | default $imgObj.Width -}}

{{- $skipConvert := in (slice "webp" "avif" "gif") $imgObj.MediaType.SubType -}}
{{- $pathInfo := partial "_internal/image/path.html" $imgObj -}}

{{- $imgDesktop := $imgObj -}}
{{- if not $skipConvert -}}
{{- $desktopLabel := "full" -}}
{{- if ne $desktopWidth $imgObj.Width -}}
{{- $desktopLabel = printf "%dpx" $desktopWidth -}}
{{- end -}}
{{- $desktopPath := printf "%s-%s_%s.webp" $pathInfo.base $desktopLabel $pathInfo.hash -}}
{{- $imgDesktop = $imgObj.Resize (printf "%dx webp lossy" $desktopWidth) | resources.Copy $desktopPath -}}
{{- end -}}

{{- $imgMobile := $imgDesktop -}}
{{- if gt $imgObj.Width 800 -}}
{{- $mobilePath := printf "%s-800px_%s.webp" $pathInfo.base $pathInfo.hash -}}
{{- $imgMobile = $imgObj.Resize "800x webp lossy" | resources.Copy $mobilePath -}}
{{- end -}}

{{- return (dict "imgObj" $imgObj "imgDesktop" $imgDesktop "imgMobile" $imgMobile) }}

使用起來像這樣:

{{- $imgObj := or (.Page.Resources.Get $path) (resources.Get $path) -}}

{{- $i := partial "_internal/image/render-hook.html" (dict "imgObj" .imgObj) -}}
<img
src="{{ .imgObj.RelPermalink }}"
alt="{{ .alt }}"
loading="lazy"
{{ with $i.imgDesktop.Width }}width="{{ . }}"{{ end }}
{{ with $i.imgDesktop.Height }}height="{{ . }}"{{ end }}
srcset="{{ printf "%s 1280w, %s 2400w" $i.imgMobile.RelPermalink $i.imgDesktop.RelPermalink }}"
sizes="(max-width: 767px) 50vw, 100vw">

resources.Copy 在在記憶體內部完成操作不會造成任何效能問題,直到 .RelPermalink 才會把資產 publish 到輸出資料夾。

當然,resources.Copy 是在記憶體內操作的事實仍然是 undocumented。