前两篇记了建站、内容组织和部署。写技术文章时很快会撞到 Markdown 的天花板:想给图片 加个标题和链接、想让代码块高亮某几行、想嵌个视频或 GitHub Gist——这些纯 Markdown 都 做不到。Hugo 的答案是 Shortcode(短代码):在 Markdown 里写一个简单标签,构建时 由模板渲染成完整 HTML,既不用手写一坨 HTML,也不用离开 Markdown 的写作流。

1. 内置 Shortcode:最常用的几个

Shortcode 用 {{< 名字 参数 >}} 或 {{% 名字 %}} 两种形式。区别是: 带百分号的写法 {{% ... %}} 里的内容会再走一遍 Markdown 渲染, 带尖括号的写法 {{< ... >}} 则原样输出。常用内置的有:

Shortcode作用
figure带标题、alt、链接的图片(比 ![]() 强)
highlight代码块,可指定语言和高亮行
gist嵌入 GitHub Gist
youtube / vimeo嵌入视频
twitter / bilibili嵌入社交/视频卡片
ref / relref生成站内文章的永久链接(防链接失效)

比如用 figure 插入一张带图注和链接的图:

{{< figure src="hugo-server.png"
    title="图 1:hugo server 实时构建"
    alt="终端里 hugo server 的输出"
    caption="保存即刷新,构建只要几十毫秒" >}}

内置 figure shortcode 的效果

它会渲染成 <figure> + <figcaption> 结构,比裸 ![]() 语义更好,主题也能统一给 图注加样式。我这几篇笔记里封面用 front matter 的 cover,正文插图大多直接用 Markdown 图片;需要图注时就换 figure。

2. 代码高亮:Chroma 与高亮行

Hugo 内置 Chroma 语法高亮器,不需要任何 JavaScript,构建时直接把代码染成带颜色的 HTML。围栏代码块指定语言即可:

```go
package main

import "fmt"

func main() {
    fmt.Println("Hello, Hugo")
}
```

想高亮某几行(比如讲重点的那一行),用 highlight shortcode 加 hl_lines:

{{< highlight go "hl_lines=5,linenos=table" >}}
package main

import "fmt"

func main() {
    fmt.Println("Hello, Hugo")
}
{{< /highlight >}}

代码高亮与行号效果

几个常用参数:

  • linenos=table:显示行号(inline 也可以,table 布局更稳);
  • hl_lines=3-5,8:高亮第 3 到 5 行和第 8 行;
  • linenostart=10:行号从 10 开始(讲文件片段时有用);
  • style=monokai:指定配色。

配色在 hugo.toml 里全局配置,也可以关掉行号、换主题风格:

[markup]
  [markup.highlight]
    style = "monokai"
    lineNos = true
    noClasses = false

noClasses = false 时 Hugo 输出带 class 的标签,需要在模板里用内置函数 {{/highlight.GetStyles "monokai"/}} 拿到高亮 CSS 并引入页面; 嫌麻烦就保持默认,让样式内联,零配置即可用。

3. 自定义 Shortcode:三行起步

内置的不够用时,自己写一个也非常简单——在 layouts/shortcodes/ 下放个模板文件, 文件名就是 shortcode 名。比如做一个"提示框" note:

layouts/shortcodes/note.html:

<div class="callout callout-note">
  <strong>💡 {{ .Get "title" | default "提示" }}</strong>
  {{ .Inner | markdownify }}
</div>

文章里这样用(注意配对的闭合标签和 .Inner):

{{< note title="小坑" >}}
`draft: true` 的文章默认**不会**发布,本地预览记得加 `--buildDrafts`。
{{< /note >}}

自定义 note shortcode 与渲染结果

几个关键 API:

  • .Get "name" / .Get 0:取命名参数或位置参数;
  • .Inner:取标签之间的内容,配 markdownify 可让里面继续支持 Markdown;
  • .Page、.Site:访问当前页面和站点变量。

带 .Inner 的叫成对 shortcode(有闭合标签),不带内容的是单标签(如 youtube)。理解了"shortcode 就是一个可传参的小模板",你就能把任何重复出现的 HTML 片段(信息框、引用卡片、目录锚点、下载按钮)都抽象成 shortcode,文章里保持干净。

小结

Shortcode 补上了 Markdown 表达能力的最后一块拼图:内置 figure/highlight 解决 九成日常需求,Chroma 让代码高亮零 JS,自定义 shortcode 让任何 HTML 片段都能被一句话 复用。 至此三篇笔记覆盖了 Hugo 的主要工作流——建站预览、内容组织与部署、模板与 shortcode 扩展。剩下的就是多写,遇到重复劳动就抽象成模板或 shortcode。