跳过正文
  1. 文章/

Hugo 内置与自定义 Shortcode

·2058 字·5 分钟·
目录

本文根据 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 或运行不受信任内容的站点,不应启用这一选项。

编写时的实践建议
#

  1. 优先使用普通 Markdown;只有重复结构或模板逻辑明显时才创建 Shortcode。
  2. 参数较多时使用命名参数,并为可选参数设置清晰的默认值。
  3. 对缺失资源和无效参数使用 errorfwarnf,让问题在构建阶段暴露。
  4. 在代码示例中使用注释转义 Shortcode,避免 Hugo 在展示示例时执行它。
  5. 外部嵌入应考虑隐私、性能和第三方内容失效问题。
  6. 行内 Shortcode 只用于内容来源完全可信的站点。

参考资料
#

freeez
作者
freeez
我会哭的很大声

相关文章