Hugo 静态网站构建实战手册

主题开发

从使用主题、覆盖主题到创建自定义主题,掌握 Hugo 主题开发的可维护实践

主题开发

Hugo 主题本质上是一组可复用的模板、样式、脚本、静态资源和示例配置。你可以直接使用主题,也可以局部覆盖主题,还可以创建自己的主题。

主题开发最重要的原则是:先用配置,再覆盖模板,最后才修改主题源码。这样升级主题时不会被自己的改动绊住。

安装主题的方式

Git submodule

最常见方式:

git submodule add https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke

配置:

theme = 'ananke'

更新主题:

git submodule update --remote themes/ananke

克隆项目后初始化:

git submodule update --init --recursive

直接克隆

git clone https://github.com/theNewDynamic/gohugo-theme-ananke.git themes/ananke

简单直接,但主题更新和你自己的修改容易混在一起。只建议临时测试。

Hugo Modules

适合大型项目和多主题依赖:

hugo mod init github.com/yourname/my-blog
hugo mod get github.com/theNewDynamic/gohugo-theme-ananke

配置:

theme = 'github.com/theNewDynamic/gohugo-theme-ananke'

或者使用模块导入:

[[module.imports]]
  path = 'github.com/theNewDynamic/gohugo-theme-ananke'

主题目录结构

themes/my-theme/
├── archetypes/
├── assets/
├── content/
├── data/
├── i18n/
├── layouts/
├── static/
├── theme.toml
└── README.md

核心目录:

  • layouts/ 放模板
  • assets/ 放需要处理的 CSS、JS、图片
  • static/ 放原样复制的资源
  • archetypes/ 放内容模板
  • i18n/ 放多语言文本
  • theme.toml 放主题元信息

覆盖主题模板

不要直接改:

themes/ananke/layouts/_default/single.html

推荐复制到站点根目录:

layouts/_default/single.html

Hugo 会优先使用站点根目录的模板。这样主题升级时,你的覆盖文件仍然保留。

常见覆盖:

layouts/partials/head.html
layouts/partials/header.html
layouts/partials/footer.html
layouts/_default/single.html
layouts/posts/list.html
layouts/shortcodes/notice.html

覆盖静态资源

主题中的:

themes/theme-name/static/images/logo.png

可以用站点文件覆盖:

static/images/logo.png

主题中的:

themes/theme-name/assets/scss/main.scss

可以通过站点文件覆盖或在主题提供的自定义入口中扩展:

assets/scss/main.scss
assets/scss/custom.scss

是否能覆盖取决于主题模板如何引用资源。

使用主题参数

主题通常通过 params 暴露配置项:

[params]
  description = '我的个人博客'

  [params.author]
    name = '你的名字'
    avatar = '/images/avatar.jpg'
    bio = '长期主义写作者'

模板中读取:

{{ site.Params.author.name }}

做主题时,建议给参数设置默认值:

{{ site.Params.author.name | default site.Title }}

这样用户少配一个字段也不会导致页面崩掉。

创建新主题

hugo new theme my-theme

会生成基础结构。然后在站点配置中启用:

theme = 'my-theme'

最小可用模板:

themes/my-theme/layouts/
├── _default/
│   ├── baseof.html
│   ├── list.html
│   └── single.html
└── index.html

基础模板设计

<!doctype html>
<html lang="{{ site.Language.LanguageCode | default "zh-CN" }}">
  <head>
    {{ partial "head.html" . }}
  </head>
  <body>
    {{ partial "header.html" . }}
    <main id="main">
      {{ block "main" . }}{{ end }}
    </main>
    {{ partial "footer.html" . }}
  </body>
</html>

主题应尽量把可复用部分拆成 partial:

partials/
├── head.html
├── seo.html
├── header.html
├── footer.html
├── post-card.html
├── pagination.html
└── comments.html

主题配置示例

可以在 README 中给出完整配置:

baseURL = 'https://example.org/'
title = 'My Blog'
theme = 'my-theme'
defaultContentLanguage = 'zh'
languageCode = 'zh-CN'

[pagination]
  pagerSize = 10

[params]
  description = 'A Hugo blog'
  mainSections = ['posts']

  [params.author]
    name = 'Author Name'
    avatar = '/images/avatar.jpg'

不要让用户从源码里猜配置项。

支持自定义 CSS 和 JS

主题可以约定自定义资源入口:

{{ with resources.Get "css/custom.css" }}
  {{ $css := . | minify | fingerprint }}
  <link rel="stylesheet" href="{{ $css.RelPermalink }}" integrity="{{ $css.Data.Integrity }}">
{{ end }}

用户只要创建:

assets/css/custom.css

即可扩展样式。

JS 也可以类似:

{{ with resources.Get "js/custom.js" }}
  {{ $js := . | js.Build | minify | fingerprint }}
  <script src="{{ $js.RelPermalink }}" integrity="{{ $js.Data.Integrity }}" defer></script>
{{ end }}

响应式与可访问性

主题开发不只是能显示,还要能长期使用。

建议:

  • 移动端优先,桌面端增强
  • 导航、按钮、表单有清晰焦点状态
  • 图片写 alt
  • 正文行宽控制在舒适范围
  • 颜色对比度足够
  • 不用 JS 也能阅读核心内容
  • 目录、面包屑、上一篇下一篇帮助读者定位

多语言支持

主题文本不要全部写死,放到 i18n/

# i18n/zh.toml
[read_more]
other = "阅读全文"

[published_on]
other = "发布于"

模板中使用:

{{ i18n "read_more" }}

评论系统集成

主题可以把评论系统做成 partial,并用参数控制:

[params.comments]
  enabled = true
  provider = 'twikoo'

模板:

{{ if site.Params.comments.enabled }}
  {{ partial (printf "comments/%s.html" site.Params.comments.provider) . }}
{{ end }}

注意不要把服务端密钥写到前端配置中。

主题开发调试

常用命令:

hugo server -D --disableFastRender
hugo --templateMetrics
hugo --templateMetricsHints
hugo --printPathWarnings
hugo --printUnusedTemplates

检查主题是否依赖 Hugo Extended:

hugo version

如果样式编译失败,先确认输出中是否包含 extended

版本与兼容性

主题 README 中应写清楚:

  • 最低 Hugo 版本
  • 是否需要 Extended
  • 是否需要 Node.js、PostCSS、Tailwind
  • 必填配置项
  • 推荐目录结构
  • 更新方式

示例:

## Requirements

- Hugo Extended 0.158.0 or newer
- Git
- Node.js 20+ if you enable Tailwind build

主题维护建议

  • 把用户可配置内容放到 params
  • 给重要参数设置默认值
  • 不直接假设某个栏目一定存在
  • Partial 命名清晰,避免一个文件过大
  • resources.Get 时处理资源不存在的情况
  • 主题示例站点保持可构建
  • 发布前用空站点测试一次

下一步

继续阅读 资源管道,学习如何处理样式、脚本和图片。

评论

0%