什么是 Partials

Partials 是 Hugo 中的可重用模板片段,允许将模板的公共部分提取为独立文件,然后在其他模板中引用。这种模块化方式可以提高代码复用性,使模板结构更清晰,便于维护。

基本语法

基本引用方式

      <!-- 引用 partial -->
{{ partial "partial-name.html" . }}

<!-- 引用带路径的 partial -->
{{ partial "path/to/partial.html" . }}

<!-- 引用带缓存的 partial -->
{{ partialCached "partial-name.html" . }}
    

动态路径引用

      <!-- 使用 printf 构建动态路径 -->
{{ partial (printf "%s/%s" ($.Scratch.Get "pathName") "head/favicon.html") . }}

<!-- 使用变量构建路径 -->
{{ $pathName := "docs" }}
{{ partial (printf "%s/%s" $pathName "sidebar.html") . }}
    

项目中的 Partials 使用示例

基础 Partial 引用

静态路径引用

      <!-- 引用 Google Fonts partial -->
{{- partialCached "google-fonts" . }}

<!-- 引用 favicon -->
{{ partialCached (printf "%s/%s" ($.Scratch.Get "pathName") "head/favicon.html") . }}
    

条件引用

      <!-- 根据配置条件引用 -->
{{ if eq .Site.Params.docs.darkMode true -}}
    {{ $darkModeInit := resources.Get (printf "/%s/%s" ($.Scratch.Get "pathName") "js/darkmode-init.js") }}
{{ end -}}

<!-- 根据页面参数引用 -->
{{ if .Params.katex }}
    {{- partialCached (printf "%s/%s" ($.Scratch.Get "pathName") "footer/katex.html") . -}}
{{ end }}
    

使用 Scratch 存储和获取路径

项目中大量使用 Scratch 来存储和获取路径名:

      <!-- 在基础模板中设置路径名 -->
{{ $.Scratch.Set "pathName" (printf "%s" (.Site.Params.docs.pathName | default "docs")) }}

<!-- 在 partial 中使用存储的路径名 -->
{{ partial (printf "%s/%s" ($.Scratch.Get "pathName") "head/favicon.html") . }}
{{- partial (printf "%s/%s" ($.Scratch.Get "pathName") "head/opengraph") . }}
    

块(Block)与 Partial 结合

      <!-- 使用 block 定义可覆盖的区域 -->
{{ block "favicon" . }}
    {{ partialCached (printf "%s/%s" ($.Scratch.Get "pathName") "head/favicon.html") . }}
{{ end }}
    

多语言环境下的 Partials

      <!-- 多语言站点使用不同的缓存策略 -->
{{ if hugo.IsMultilingual }}
    {{- partial (printf "%s/%s" ($.Scratch.Get "pathName") "top-header.html") . -}}
{{ else }}
    {{- partialCached (printf "%s/%s" ($.Scratch.Get "pathName") "top-header.html") . .RelPermalink -}}
{{ end }}
    

参数传递给 Partial

传递上下文

      <!-- 传递完整上下文 -->
{{ partial "sidebar.html" . }}

<!-- 传递特定数据 -->
{{ partial "components/card.html" (dict "title" "标题" "content" "内容" "page" .) }}
    

在 Partial 中接收参数

      <!-- filepath: layouts/partials/components/card.html -->
{{ $title := .title }}
{{ $content := .content }}
{{ $page := .page }}

<div class="card">
    <h2>{{ $title }}</h2>
    <p>{{ $content }}</p>
    <!-- 可以访问页面数据 -->
    <span>{{ $page.Site.Title }}</span>
</div>
    

Partials 缓存策略

partialCached 的使用

partialCached 可以缓存 partial 的渲染结果,提高构建性能:

      <!-- 基本缓存 -->
{{ partialCached "footer.html" . }}

<!-- 基于变量缓存 -->
{{ partialCached "navigation.html" . .Section }}

<!-- 基于多个变量缓存 -->
{{ partialCached "sidebar.html" . .Section .Params.category }}
    

缓存变体

      <!-- 基于页面路径缓存 -->
{{ partialCached "breadcrumbs.html" . .RelPermalink }}

<!-- 基于页面类型缓存 -->
{{ partialCached "page-header.html" . .Type }}

<!-- 基于自定义变量缓存 -->
{{ partialCached "component.html" . .Params.layout .Section }}
    

命名规范

  • 使用小写字母和连字符:sidebar.htmltop-header.html
  • 按功能分组:docs/head/docs/footer/
  • 使用描述性名称:breadcrumbs.htmltoc-mobile.html

高级用法

动态 Partial 选择

      <!-- 根据页面类型选择不同的 partial -->
{{ $partialName := printf "components/header-%s.html" .Type }}
{{ partial $partialName . }}

<!-- 根据配置选择 partial -->
{{ if .Site.Params.docs.darkMode }}
    {{ partial "components/dark-header.html" . }}
{{ else }}
    {{ partial "components/light-header.html" . }}
{{ end }}
    

Partial 嵌套

      <!-- partials/docs/head.html -->
<head>
    <!-- 嵌套其他 partials -->
    {{ partial "docs/head/favicon.html" . }}
    {{ partial "docs/head/opengraph.html" . }}
    {{ partial "docs/head/twitter_cards.html" . }}
</head>
    

Partial 与数据结合

      <!-- 使用数据文件驱动 partial 渲染 -->
{{ range .Site.Data.nav.items }}
    {{ partial "components/nav-item.html" . }}
{{ end }}
    

条件渲染 Partial

      <!-- 仅在生产环境渲染 -->
{{ if hugo.IsProduction }}
    {{ partial "analytics.html" . }}
{{ end }}

<!-- 根据页面参数渲染 -->
{{ if .Params.showToc }}
    {{ partial "docs/toc.html" . }}
{{ end }}
    

最佳实践

模块化设计

  • 将相关功能组织在同一目录下
  • 保持 partial 的单一职责
  • 避免创建过于复杂的 partial

参数传递

  • 使用字典传递多个参数:dict "key1" "value1" "key2" "value2"
  • 传递页面上下文以便访问页面数据
  • 避免在 partial 中直接访问全局变量

缓存策略

  • 对不常变化的内容使用 partialCached
  • 基于相关变量设置缓存键
  • 避免过度缓存导致内容更新不及时

性能优化

  • 减少不必要的 partial 嵌套
  • 合理使用缓存策略
  • 避免在 partial 中执行耗时操作

常见问题与解决方案

Partial 找不到

确保 partial 文件路径正确,特别是在使用动态路径时:

      <!-- 检查路径是否正确 -->
{{ $path := printf "%s/%s" ($.Scratch.Get "pathName") "partial-name.html" }}
{{ partial $path . }}
    

缓存问题

如果内容更新后没有反映,检查缓存键是否合适:

      <!-- 使用更具体的缓存键 -->
{{ partialCached "sidebar.html" . .Section .Params.version }}
    

上下文丢失

确保传递正确的上下文:

      <!-- 传递完整上下文 -->
{{ partial "component.html" . }}

<!-- 或显式传递所需数据 -->
{{ partial "component.html" (dict "page" . "site" .Site) }}
    

总结

Partials 是 Hugo 中强大的模板组织工具,通过合理使用可以提高代码复用性、维护性和性能。在项目中,建议:

  1. 按功能组织 partials 目录结构
  2. 使用描述性命名规范
  3. 合理使用缓存策略
  4. 保持 partial 的简单和专注
  5. 传递明确的上下文和参数

通过遵循这些最佳实践,可以构建出清晰、高效、可维护的 Hugo 模板系统。

声明

作者: liyao

版权:本博客所有文章除特别声明外,均采用CCBY-NC-SA4.O许可协议。转载请注明!

最后更新于 2025-12-20 17:30 history