HUGO

  • 新闻
  • 文档
  • 主题
  • 社区
  • GitHub
gohugoio Star
  • 关于
    • 本节内容
    • 介绍
    • 特性
    • 隐私
    • 安全
    • 许可证
  • 安装
    • 本节内容
    • macOS
    • Linux
    • Windows
    • BSD
  • 入门
    • 本节内容
    • 快速开始
    • 基本用法
    • 目录结构
    • 配置
    • 配置标记
    • 配置构建
    • 术语表
    • 外部学习资源
  • 快速参考
    • 本节内容
    • 表情符号
    • 函数
    • 方法
    • 页面集合
  • 内容管理
    • 本节内容
    • 组织
    • 页面包
    • 内容格式
    • 前言
    • 构建选项
    • 页面资源
    • 图像处理
    • 短代码
    • 相关内容
    • 章节
    • 内容类型
    • 原型
    • 分类
    • 摘要
    • 链接和交叉引用
    • URL 管理
    • 菜单
    • 评论
    • 多语言
    • Markdown 属性
    • 语法高亮
    • 图表
    • 数学
    • 数据源
    • 内容适配器
  • 模板
    • 本节内容
    • 介绍
    • 模板类型
    • 查找顺序
    • 基础模板
    • 主页模板
    • 单页模板
    • 章节模板
    • 分类模板
    • 术语模板
    • 部分模板
    • 内容视图模板
    • 短代码模板
    • 站点地图模板
    • RSS 模板
    • 404 模板
    • robots.txt 模板
    • 菜单
    • 分页
    • 嵌入式模板
    • 自定义输出格式
  • 函数
    • 本节内容
    • 类型转换
    • 集合
    • 比较
    • 加密
    • css
    • 数据
    • 调试
    • 图表
    • 编码
    • 格式
    • 全局
    • Go 模板
    • 哈希
    • hugo
    • 图像
    • 词形变化
    • js
    • 语言
    • 数学
    • openapi3
    • os
    • partials
    • 路径
    • 反射
    • 资源
    • 安全
    • 字符串
    • 模板
    • 时间
    • 转换
    • urls
  • 方法
    • 本节内容
    • 持续时间
    • 菜单
    • 菜单项
    • 页面
    • 分页器
    • 页面集
    • 资源
    • 短代码
    • 站点
    • 分类
    • 时间
  • 渲染钩子
    • 本节内容
    • 介绍
    • 块引用
    • 代码块
    • 标题
    • 图像
    • 链接
    • 透传
    • 表格
  • 短代码
    • 本节内容
    • 评论
    • 详情
    • 图示
    • Gist
    • 高亮
    • Instagram
    • 参数
    • 二维码
    • 引用
    • 相对引用
    • Vimeo
    • X
    • YouTube
  • Hugo 模块
    • 本节内容
    • 配置 Hugo 模块
    • 使用 Hugo 模块
    • 主题组件
  • Hugo Pipes
    • 本节内容
    • 介绍
    • 将 Sass 转译为 CSS
    • PostCSS
    • 后期处理
    • JavaScript 构建
    • 资源压缩
    • 连接资源
    • 指纹识别和 SRI 哈希
    • 从字符串创建资源
    • 从模板创建资源
  • CLI
  • 故障排除
    • 本节内容
    • 审计
    • 日志
    • 检查
    • 弃用
    • 性能
    • 常见问题
  • 开发者工具
    • 本节内容
    • 编辑器插件
    • 前端
    • 搜索
    • 迁移
    • 其他项目
  • 托管和部署
    • 本节内容
    • Hugo 部署
    • 使用 Rclone 部署
    • 使用 Rsync 部署
    • 在 21YunBox 上托管
    • 在 AWS Amplify 上托管
    • 在 Azure 静态 Web 应用上托管
    • 在 Cloudflare Pages 上托管
    • 在 Firebase 上托管
    • 在 GitHub Pages 上托管
    • 在 GitLab Pages 上托管
    • 在 KeyCDN 上托管
    • 在 Netlify 上托管
    • 在 Render 上托管
  • 贡献
    • 本节内容
    • 开发
    • 文档
    • 主题
  • 维护
模板

创建你自己的短代码

你可以通过使用与单页和列表页相同的模板语法创建自己的短代码来扩展 Hugo 的内置短代码。

短代码是一种将模板整合到小的、可重用的片段中的方法,你可以将这些片段直接嵌入到你的内容中。

Hugo 还附带了针对常见用例的嵌入式短代码。(请参阅 内容管理:短代码。)

创建自定义短代码

Hugo 的内置短代码涵盖了许多常见但并非全部的用例。幸运的是,Hugo 提供了轻松创建自定义短代码来满足你的网站需求的功能。

文件位置

要创建短代码,请将 HTML 模板放在 layouts/shortcodes 目录中。仔细考虑文件名,因为短代码名称将镜像该文件名,但不包含 .html 扩展名。例如,layouts/shortcodes/myshortcode.html 将使用 {{< myshortcode />}} 或 {{% myshortcode /%}} 调用。

你可以将短代码组织在子目录中,例如在 layouts/shortcodes/boxes 中。然后,这些短代码将可以通过其相对路径访问,例如

{{< boxes/square >}}

注意正斜杠。

模板查找顺序

Hugo 根据短代码名称、当前输出格式和当前语言选择短代码模板。下面的示例按特异性降序排序。最不具体的路径在列表底部。

短代码名称 输出格式 语言 模板路径
foo html zh layouts/shortcodes/foo.zh.html
foo html zh layouts/shortcodes/foo.html.html
foo html zh layouts/shortcodes/foo.html
foo html zh layouts/shortcodes/foo.html.zh.html
短代码名称 输出格式 语言 模板路径
foo rss zh layouts/shortcodes/foo.zh.xml
foo rss zh layouts/shortcodes/foo.rss.xml
foo rss zh layouts/shortcodes/foo.zh.html
foo rss zh layouts/shortcodes/foo.rss.zh.xml
foo rss zh layouts/shortcodes/foo.xml
foo rss zh layouts/shortcodes/foo.html.zh.html
foo rss zh layouts/shortcodes/foo.html.html
foo rss zh layouts/shortcodes/foo.html

请注意,主题或模块提供的模板始终优先。

位置参数与命名参数

你可以使用以下类型的参数创建短代码

  • 位置参数
  • 命名参数
  • 位置参数或命名参数

在具有位置参数的短代码中,参数的顺序很重要。如果短代码具有单个必需值,则位置参数需要内容作者较少的输入。

对于具有多个或可选参数的更复杂的布局,命名参数效果最佳。虽然不如简洁,但命名参数需要内容作者较少的记忆,并且可以按任何顺序添加到短代码声明中。

允许两种类型的参数对于复杂的布局很有用,在这种布局中,你希望设置可以被用户轻松覆盖的默认值。

访问参数

所有短代码参数都可以通过 .Get 方法访问。你是向 .Get 方法传递字符串还是数字取决于你是访问命名参数还是位置参数。

要按名称访问参数,请使用 .Get 方法,后跟以引号括起来的命名参数

{{ .Get "class" }}

要按位置访问参数,请使用 .Get 后跟数字位置,请记住位置参数从零开始索引

{{ .Get 0 }}

对于第二个位置,你只需使用

{{ .Get 1 }}

当输出取决于是否设置了参数时,with 非常有用

{{ with .Get "class" }} class="{{ . }}"{{ end }}

.Get 也可以用来检查是否已提供参数。当条件取决于其中一个或两个值时,这最有用

{{ if or (.Get "title") (.Get "alt") }} alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "title" }}{{ end }}"{{ end }}

.Inner

.Inner 方法返回开始和结束短代码标记之间的内容。要检查 .Inner 是否返回除空格之外的任何内容

{{ if strings.ContainsNonSpace .Inner }}
  Inner is not empty
{{ end }}

任何调用 .Inner 方法的短代码都必须关闭或自关闭。要使用自关闭语法调用短代码。

{{< innershortcode />}}

.Params

短代码中的 .Params 方法返回传递给短代码的参数,以用于更复杂的用例。你还可以使用以下逻辑访问更高范围的参数

$.Params
这些是直接传递到短代码声明中的参数(例如,YouTube 视频 ID)
$.Page.Params
指页面的参数;这里的“页面”指的是声明短代码的内容文件(例如,可以通过 $.Page.Params.shortcode_color 访问内容前言中的 shortcode_color 字段)。
$.Site.Params
指在站点配置中定义的参数。

.IsNamedParams

.IsNamedParams 方法检查短代码声明是否使用了命名参数,并返回一个布尔值。

例如,您可以创建一个 image 短代码,它可以接受一个 src 命名参数或第一个位置参数,具体取决于内容作者的偏好。假设 image 短代码的调用方式如下

{{< image src="images/my-image.jpg" >}}

然后,您可以将以下内容作为短代码模板的一部分包含进来

{{ if .IsNamedParams }}
  <img src="{{ .Get "src" }}" alt="">
{{ else }}
  <img src="{{ .Get 0 }}" alt="">
{{ end }}

有关 .IsNamedParams 的实际应用,请参阅下面的 Vimeo 短代码示例。

虽然您可以创建接受位置参数和命名参数的短代码模板,但您不能在内容中使用混合参数类型的短代码声明。因此,像 {{< image src="images/my-image.jpg" "这是我的 alt 文本" >}} 这样的短代码声明将返回错误。

短代码也可以嵌套。在嵌套的短代码中,您可以使用 .Parent 短代码方法访问父短代码上下文。这对于从根继承非常有用。

检查是否存在

您可以通过在页面模板中调用 .HasShortcode 并提供短代码的名称来检查特定短代码是否在页面上使用。当您想在头部包含仅由该短代码使用的特定脚本或样式时,这非常有用。

自定义短代码示例

以下是通过 /layouts/shortcodes 中的短代码模板文件创建的不同类型短代码的示例。

单字示例:year

假设您希望在内容文件中保持版权年份的最新状态,而无需不断检查 Markdown。您的目标是能够按如下方式调用短代码

{{< year >}}
layouts/shortcodes/year.html
{{ now.Format "2006" }}

单位置示例:youtube

嵌入视频是 Markdown 内容的常见添加项。以下是 Hugo 内置 YouTube 短代码使用的代码

{{< youtube 09jf3ow9jfw >}}

将加载 /layouts/shortcodes/youtube.html 的模板

layouts/shortcodes/youtube.html
<div class="embed video-player">
<iframe class="youtube-player" type="text/html" width="640" height="385" src="https://www.youtube.com/embed/{{ index .Params 0 }}" allowfullscreen frameborder="0">
</iframe>
</div>
youtube-embed.html
<div class="embed video-player">
    <iframe class="youtube-player" type="text/html"
        width="640" height="385"
        src="https://www.youtube.com/embed/09jf3ow9jfw"
        allowfullscreen frameborder="0">
    </iframe>
</div>

单命名示例:image

假设您想创建自己的 img 短代码,而不是使用 Hugo 内置的 figure 短代码。您的目标是能够在内容文件中按如下方式调用短代码

content-image.md
{{< img src="/media/spf13.jpg" title="Steve Francia" >}}

您已经在 /layouts/shortcodes/img.html 中创建了短代码,它将加载以下短代码模板

layouts/shortcodes/img.html
<!-- image -->
<figure {{ with .Get "class" }}class="{{ . }}"{{ end }}>
  {{ with .Get "link" }}<a href="{{ . }}">{{ end }}
    <img src="{{ .Get "src" }}" {{ if or (.Get "alt") (.Get "caption") }}alt="{{ with .Get "alt" }}{{ . }}{{ else }}{{ .Get "caption" }}{{ end }}"{{ end }} />
    {{ if .Get "link" }}</a>{{ end }}
    {{ if or (or (.Get "title") (.Get "caption")) (.Get "attr") }}
      <figcaption>{{ if isset .Params "title" }}
        <h4>{{ .Get "title" }}</h4>{{ end }}
        {{ if or (.Get "caption") (.Get "attr") }}<p>
        {{ .Get "caption" }}
        {{ with .Get "attrlink" }}<a href="{{ . }}"> {{ end }}
          {{ .Get "attr" }}
        {{ if .Get "attrlink" }}</a> {{ end }}
        </p> {{ end }}
      </figcaption>
  {{ end }}
</figure>
<!-- image -->

将呈现为

img-output.html
<figure>
  <img src="/media/spf13.jpg"  />
  <figcaption>
      <h4>Steve Francia</h4>
  </figcaption>
</figure>

单灵活示例:vimeo

{{< vimeo 49718712 >}}
{{< vimeo id="49718712" class="flex-video" >}}

将加载位于 /layouts/shortcodes/vimeo.html 的模板

layouts/shortcodes/vimeo.html
{{ if .IsNamedParams }}
  <div class="{{ if .Get "class" }}{{ .Get "class" }}{{ else }}vimeo-container{{ end }}">
    <iframe src="https://player.vimeo.com/video/{{ .Get "id" }}" allowfullscreen></iframe>
  </div>
{{ else }}
  <div class="{{ if len .Params | eq 2 }}{{ .Get 1 }}{{ else }}vimeo-container{{ end }}">
    <iframe src="https://player.vimeo.com/video/{{ .Get 0 }}" allowfullscreen></iframe>
  </div>
{{ end }}

将呈现为

vimeo-iframes.html
<div class="vimeo-container">
  <iframe src="https://player.vimeo.com/video/49718712" allowfullscreen></iframe>
</div>
<div class="flex-video">
  <iframe src="https://player.vimeo.com/video/49718712" allowfullscreen></iframe>
</div>

成对示例:highlight

以下内容取自 highlight,它是 Hugo 自带的内置短代码。

highlight-example.md
{{< highlight html >}}
  <html>
    <body> This HTML </body>
  </html>
{{< /highlight >}}

highlight 短代码的模板使用以下代码,该代码已包含在 Hugo 中

{{ .Get 0 | highlight .Inner }}

HTML 示例代码块的呈现输出将如下所示

syntax-highlighted.html
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f92672">&lt;html&gt;</span>
    <span style="color: #f92672">&lt;body&gt;</span> This HTML <span style="color: #f92672">&lt;/body&gt;</span>
<span style="color: #f92672">&lt;/html&gt;</span>
</pre></div>

嵌套短代码:图片库

当所讨论的短代码在父短代码的上下文中调用时,Hugo 的 .Parent 短代码方法提供对父短代码上下文的访问权限。这提供了一个继承模型。

以下示例是人为设计的,但演示了该概念。假设您有一个 gallery 短代码,它需要一个名为 class 的命名参数

layouts/shortcodes/gallery.html
<div class="{{ .Get "class" }}">
  {{ .Inner }}
</div>

您还有一个 img 短代码,它具有一个名为 src 的命名参数,您想在 gallery 和其他短代码内部调用它,以便父短代码定义每个 img 的上下文

layouts/shortcodes/img.html
{{- $src := .Get "src" -}}
{{- with .Parent -}}
  <img src="{{ $src }}" class="{{ .Get "class" }}-image">
{{- else -}}
  <img src="{{ $src }}">
{{- end -}}

然后,您可以在内容中按如下方式调用短代码

{{< gallery class="content-gallery" >}}
  {{< img src="/images/one.jpg" >}}
  {{< img src="/images/two.jpg" >}}
{{< /gallery >}}
{{< img src="/images/three.jpg" >}}

这将输出以下 HTML。请注意,前两个 img 短代码如何继承通过调用父 gallery 设置的 content-gallery 的 class 值,而第三个 img 仅使用 src

<div class="content-gallery">
    <img src="/images/one.jpg" class="content-gallery-image">
    <img src="/images/two.jpg" class="content-gallery-image">
</div>
<img src="/images/three.jpg">

短代码中的错误处理

使用 errorf 模板函数和 Name 以及 Position 短代码方法来生成有用的错误消息

layouts/shortcodes/greeting.html
{{ with .Get "name" }}
  <p>Hello, my name is {{ . }}.</p>
{{ else }}
  {{ errorf "The %q shortcode requires a 'name' argument. See %s" .Name .Position }}
{{ end }}

当上述操作失败时,您将看到类似如下的 ERROR 消息

ERROR The "greeting" shortcode requires a 'name' argument. See "/home/user/project/content/_index.md:12:1"

内联短代码

您还可以在内联实现您的短代码 - 例如,在您在内容文件中使用它们的地方。这对于您只需要在一个地方使用的脚本可能很有用。

此功能默认处于禁用状态,但可以在您的站点配置中启用

hugo。
     
security:
  enableInlineShortcodes: true
[security]
  enableInlineShortcodes = true
{
   "security": {
      "enableInlineShortcodes": true
   }
}

出于安全原因,默认情况下禁用它。Hugo 的模板处理使用的安全模型假定模板作者是受信任的,但内容文件不是,因此模板可以安全地防止畸形输入数据注入。但在大多数情况下,您也可以完全控制内容,然后 enableInlineShortcodes = true 被认为是安全的。但需要注意一点:它允许从内容文件中执行临时的 Go 文本模板。

一旦启用,您就可以在内容文件中执行此操作

{{< time.inline >}}{{ now }}{{< /time.inline >}}

以上操作将打印当前的日期和时间。

请注意,内联短代码的内部内容会作为 Go 文本模板进行解析和执行,其上下文与常规短代码模板相同。

这意味着可以通过 .Page.Title 等访问当前页面。这也意味着不存在“嵌套的内联短代码”的概念。

如果需要,可以使用自闭合语法在同一内容文件中稍后重用相同的内联短代码,并使用不同的参数

{{< time.inline />}}

另请参阅

  • 代码块
  • 前言
  • 透传
  • 短代码

在此页面上

  • 创建自定义短代码
  • 自定义短代码示例
  • 短代码中的错误处理
  • 内联短代码
上次更新时间:2025 年 1 月 16 日:将目录名、文件名和文件路径格式化为代码 (8051ff818)
改进此页面
由 Hugo 作者
Hugo Logo
  • 提交问题
  • 获取帮助
  • @GoHugoIO
  • @spf13
  • @bepsays

Netlify badge

 

Hugo 赞助商

您的公司?
 

Hugo 徽标版权归 © Steve Francia 2013–2025 所有。

Hugo Gopher 基于 Renée French 的原创作品。

  • 新闻
  • 文档
  • 主题
  • 社区
  • GitHub
  • 关于
  • 安装
  • 入门
  • 快速参考
  • 内容管理
  • 模板
  • 函数
  • 方法
  • 渲染钩子
  • 短代码
  • Hugo 模块
  • Hugo Pipes
  • CLI
  • 故障排除
  • 开发者工具
  • 托管和部署
  • 贡献
  • 维护