本文根据 Hugo 官方 Shortcodes 文档重新整理,并结合本站使用的 Hugo 版本补充示例。原始文档采用 Apache License 2.0,本文已进行中文翻译、结构调整和内容修改。
Shortcode 是一种可以在 Markdown 内容中调用的 Hugo 模板。它适合封装视频、图片、提示框等重复出现的结构,也能把较复杂的模板逻辑隐藏在简短、统一的调用语法后面。
Hugo 将 Shortcode 分成三类:
- 内置 Shortcode:由 Hugo 自身提供,无需在项目中创建模板。
- 自定义 Shortcode:由站点或主题在
layouts/_shortcodes/中实现。 - 行内 Shortcode:直接在内容文件中定义,默认禁用,只适合内容作者可信的场景。
本文介绍的是 Hugo 本身的能力。Blowfish 主题额外提供的组件请参阅 Blowfish 简码示例。
内置 Shortcode#
Hugo 当前提供以下内置 Shortcode:
| 名称 | 用途 |
|---|---|
details | 生成可展开和折叠的详情区域 |
figure | 插入带标题、替代文本等属性的图片 |
highlight | 输出带语法高亮的代码 |
instagram | 嵌入 Instagram 帖子 |
param | 读取页面 Front Matter 或站点配置参数 |
qr | 生成二维码 |
ref | 生成指向其他内容页的永久链接 |
relref | 生成指向其他内容页的相对链接 |
vimeo | 嵌入 Vimeo 视频 |
x | 嵌入 X 帖子 |
youtube | 嵌入 YouTube 视频 |
具体参数可能随 Hugo 版本变化,应以每个 内置 Shortcode 的官方文档为准。
details#
details 接受内部内容,适合放置补充说明:
{{< details summary="展开查看命令" >}}
```bash
hugo server --buildDrafts
```
{{< /details >}}figure#
figure 使用命名参数描述图片:
{{< figure
src="/images/example.jpg"
alt="示例图片"
caption="图片说明"
loading="lazy"
>}}highlight#
highlight 可以高亮内部代码,并传递行号等选项:
{{< highlight go "linenos=table" >}}
package main
func main() {
println("Hello, Hugo")
}
{{< /highlight >}}普通围栏代码块同样支持语法高亮;只有需要 Shortcode 参数时才有必要使用 highlight。
ref 与 relref#
这两个 Shortcode 根据 Hugo 内容树解析目标页面,比手写最终 URL 更适合站内链接:
[绝对链接]({{< ref "/posts/blowfish-shortcodes" >}})
[相对链接]({{< relref "/posts/blowfish-shortcodes" >}})ref 返回永久链接,relref 返回相对链接。目标不存在时,Hugo 会在构建阶段报告问题。
qr#
二维码内容既可以写在成对标签之间,也可以作为参数传入:
{{< qr >}}
https://blog.freeez.cn/
{{< /qr >}}
{{< qr text="https://blog.freeez.cn/" />}}外部内容嵌入#
YouTube、Vimeo、Instagram 和 X Shortcode 通常接收资源 ID:
{{< youtube w7Ft2ymGmfc >}}
{{< vimeo 55073825 >}}
{{< instagram CxOWiQNP2MO >}}
{{< x user="GoHugoIO" id="1894377389761900814" >}}这类嵌入会连接第三方服务,可能影响页面加载速度、访客隐私和内容可用性。发布前应实际预览,并确认第三方内容仍然存在。
调用语法#
一个 Shortcode 调用由标签、参数和标记方式组成。
命名参数与位置参数#
位置参数依赖顺序:
{{< youtube w7Ft2ymGmfc >}}命名参数显式写出名称,更适合参数较多的调用:
{{< figure src="/images/example.jpg" alt="示例图片" loading="lazy" >}}同一次调用不能混用命名参数和位置参数。包含空格的字符串必须使用引号,多参数调用也可以分行书写。
< > 与 % %#
Hugo 支持两种 Shortcode 标记:
{{< foo >}}普通标记{{< /foo >}}
{{% foo %}}Markdown 标记{{% /foo %}}{{< ... >}}将 Shortcode 输出作为已经渲染的内容合并到页面中。{{% ... %}}会让 Shortcode 输出继续经过 Markdown 渲染。
例如,自定义 Shortcode 只是输出 {{ .Inner }} 时,使用 % 标记传入的 Markdown 标题会变成真正的标题,并可能进入文章目录;使用 < 标记时,内部 Markdown 不会以相同方式参与页面的 Markdown 渲染。
Shortcode 作者应根据模板输出选择合适的方式,文章作者则应遵循该 Shortcode 的使用说明。
自定义 Shortcode#
自定义 Shortcode 放在项目的 layouts/_shortcodes/ 目录。文件名就是调用时使用的名称。
下面实现一个音频播放器:
{{ with resources.Get (.Get "src") }}
<audio controls preload="metadata" src="{{ .RelPermalink }}">
当前浏览器不支持音频播放。
</audio>
{{ else }}
{{ errorf "audio shortcode: resource %q not found" (.Get "src") }}
{{ end }}把音频文件放入 assets/audio/test.mp3,然后在文章中调用:
{{< audio src="audio/test.mp3" >}}这个模板使用了几个常见对象和方法:
.Get "src"读取命名参数。resources.Get从全局资源中查找文件。.RelPermalink获取处理后资源的相对 URL。errorf在资源缺失时主动中止构建,避免发布一个失效播放器。
处理内部内容#
需要开始和结束标签时,可以通过 .Inner 读取内部内容:
<section class="panel">
{{ .Inner | markdownify }}
</section>调用方式如下:
{{< panel >}}
这里可以放置 **Markdown** 内容。
{{< /panel >}}模板是否应该调用 markdownify,取决于它与 < >、% % 标记的约定。应避免对同一段内容重复进行 Markdown 渲染。
嵌套#
普通 Shortcode 可以嵌套。例如图库可以包含多个图片 Shortcode:
{{< gallery >}}
{{< image src="/images/a.jpg" >}}
{{< image src="/images/b.jpg" >}}
{{< /gallery >}}父模板可以通过 .Inner 处理子 Shortcode 的输出。嵌套层级较深时,应特别留意渲染顺序和空白控制。
行内 Shortcode#
行内 Shortcode 把模板定义直接放进内容文件。Hugo 默认禁用此功能,因为模板可以执行远超普通 Markdown 的逻辑。
只有在所有内容作者都可信时,才应在配置中开启:
[security]
enableInlineShortcodes = true下面定义一个接受日期格式的位置参数的行内 Shortcode,并再次调用它:
{{< date.inline ":date_medium" >}}
{{- now | time.Format (.Get 0) -}}
{{< /date.inline >}}
今天是 {{< date.inline ":date_full" />}}。行内 Shortcode 不能嵌套。对多人投稿、从外部同步 Markdown 或运行不受信任内容的站点,不应启用这一选项。
编写时的实践建议#
- 优先使用普通 Markdown;只有重复结构或模板逻辑明显时才创建 Shortcode。
- 参数较多时使用命名参数,并为可选参数设置清晰的默认值。
- 对缺失资源和无效参数使用
errorf或warnf,让问题在构建阶段暴露。 - 在代码示例中使用注释转义 Shortcode,避免 Hugo 在展示示例时执行它。
- 外部嵌入应考虑隐私、性能和第三方内容失效问题。
- 行内 Shortcode 只用于内容来源完全可信的站点。


