短代码
短代码(Shortcodes)是在 Markdown 内容中插入复杂内容的方式。本章将介绍如何使用和创建短代码。
什么是短代码?
Markdown 格式虽然简洁,但有些功能无法直接实现,比如嵌入视频、图片画廊、代码高亮等。短代码允许你在 Markdown 中插入这些复杂功能,同时保持内容的可读性。
短代码的基本语法:
<!-- 无参数 -->
{{< shortcode >}}
<!-- 有参数 -->
{{< shortcode param1="value1" param2="value2" >}}
<!-- 包含内容 -->
{{< shortcode >}}
内部内容
{{< /shortcode >}}
内置短代码
Hugo 提供了一些常用的内置短代码。
figure - 图片
{{< figure src="/images/photo.jpg" title="图片标题" alt="图片描述" >}}
完整参数:
{{< figure
src="/images/photo.jpg"
link="https://example.com"
target="_blank"
title="点击查看大图"
alt="风景照片"
caption="这是图片说明"
attr="作者"
attrlink="https://example.com/author"
width="600px"
height="400px"
class="my-image"
>}}
youtube - YouTube 视频
{{< youtube id="VIDEO_ID" >}}
<!-- 或直接使用 URL -->
{{< youtube https://www.youtube.com/watch?v=VIDEO_ID >}}
<!-- 带参数 -->
{{< youtube id="VIDEO_ID" autoplay="true" start="30" >}}
vimeo - Vimeo 视频
{{< vimeo id="VIDEO_ID" >}}
gist - GitHub Gist
<!-- 整个 Gist -->
{{< gist username gist_id >}}
<!-- 特定文件 -->
{{< gist username gist_id filename.py >}}
instagram - Instagram 嵌入
{{< instagram POST_ID >}}
twitter - Twitter 嵌入
{{< twitter user="username" id="TWEET_ID" >}}
highlight - 代码高亮
{{< highlight python "linenos=table,hl_lines=2 3" >}}
def hello():
print("Hello, Hugo!")
return True
{{< /highlight >}}
参数说明:
linenos=table:显示行号(表格形式)linenos=inline:显示行号(内联形式)hl_lines="2 3":高亮第 2、3 行
code - 代码文件
{{< code file="main.py" lang="python" >}}
def main():
print("Hello")
{{< /code >}}
ref 和 relref - 页面引用
<!-- 绝对 URL -->
[关于页面]({{< ref "about.md" >}})
<!-- 相对 URL -->
[关于页面]({{< relref "about.md" >}})
<!-- 引用特定章节 -->
[章节]({{< relref "posts/my-post#introduction" >}})
创建自定义短代码
自定义短代码放在 layouts/shortcodes/ 目录下。
简单短代码
创建一个简单的提示框短代码:
layouts/shortcodes/note.html:
<div class="note">
<strong>注意:</strong> {{ .Inner }}
</div>
使用:
{{< note >}}这是一个重要提示{{< /note >}}
带参数的短代码
创建一个带类型参数的提示框:
layouts/shortcodes/alert.html:
{{ $type := .Get "type" | default "info" }}
{{ $title := .Get "title" | default "" }}
<div class="alert alert-{{ $type }}">
{{ with $title }}
<div class="alert-title">{{ . }}</div>
{{ end }}
<div class="alert-content">
{{ .Inner | markdownify }}
</div>
</div>
使用:
{{< alert type="warning" title="警告" >}}
这是一条警告信息,支持 **Markdown** 格式。
{{< /alert >}}
{{< alert type="success" >}}
操作成功完成!
{{< /alert >}}
获取参数的方式
<!-- 获取位置参数 -->
{{ .Get 0 }} <!-- 第一个参数 -->
{{ .Get 1 }} <!-- 第二个参数 -->
<!-- 获取命名参数 -->
{{ .Get "title" }}
{{ .Get "class" }}
<!-- 使用默认值 -->
{{ .Get "type" | default "info" }}
<!-- 检查参数是否存在 -->
{{ if .Get "image" }}
<img src="{{ .Get "image" }}">
{{ end }}
处理内部内容
<!-- 原样输出 -->
{{ .Inner }}
<!-- 解析 Markdown -->
{{ .Inner | markdownify }}
<!-- 转义 HTML -->
{{ .Inner | plainify }}
无闭合标签的短代码
创建图片画廊短代码:
layouts/shortcodes/gallery.html:
{{ $images := .Get "images" }}
{{ $class := .Get "class" | default "gallery" }}
<div class="{{ $class }}">
{{ range split $images "," }}
{{ $img := trim . " " }}
<figure>
<img src="{{ $img }}" alt="">
</figure>
{{ end }}
</div>
使用:
{{< gallery images="/img/1.jpg, /img/2.jpg, /img/3.jpg" class="my-gallery" >}}
实用短代码示例
代码演示
创建一个带标题和说明的代码块:
layouts/shortcodes/codedemo.html:
{{ $lang := .Get "lang" | default "text" }}
{{ $title := .Get "title" | default "代码示例" }}
{{ $desc := .Get "desc" }}
<div class="code-demo">
<div class="code-header">
<span class="code-title">{{ $title }}</span>
{{ with $desc }}
<span class="code-desc">{{ . }}</span>
{{ end }}
</div>
<div class="code-content">
{{ highlight .Inner $lang "" }}
</div>
</div>
使用:
{{< codedemo lang="python" title="Hello World" desc="简单的打印示例" >}}
print("Hello, World!")
{{< /codedemo >}}
折叠内容
创建可折叠的内容区域:
layouts/shortcodes/collapse.html:
{{ $title := .Get "title" | default "点击展开" }}
{{ $open := .Get "open" | default false }}
<details {{ if $open }}open{{ end }}>
<summary>{{ $title }}</summary>
<div class="collapse-content">
{{ .Inner | markdownify }}
</div>
</details>
使用:
{{< collapse title="查看详细说明" >}}
这里是详细说明内容,支持 **Markdown** 格式。
{{< /collapse >}}
外部链接
创建带图标的链接:
layouts/shortcodes/extlink.html:
{{ $url := .Get 0 }}
{{ $text := .Get 1 | default $url }}
<a href="{{ $url }}" target="_blank" rel="noopener noreferrer" class="external-link">
{{ $text }}
<svg class="icon" viewBox="0 0 24 24">
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
<polyline points="15 3 21 3 21 9"></polyline>
<line x1="10" y1="14" x2="21" y2="3"></line>
</svg>
</a>
使用:
{{< extlink "https://gohugo.io" "Hugo 官网" >}}
图片对比
创建并排对比的图片展示:
layouts/shortcodes/compare.html:
{{ $before := .Get "before" }}
{{ $after := .Get "after" }}
{{ $beforeLabel := .Get "beforeLabel" | default "之前" }}
{{ $afterLabel := .Get "afterLabel" | default "之后" }}
<div class="image-compare">
<div class="compare-item">
<img src="{{ $before }}" alt="{{ $beforeLabel }}">
<span class="label">{{ $beforeLabel }}</span>
</div>
<div class="compare-item">
<img src="{{ $after }}" alt="{{ $afterLabel }}">
<span class="label">{{ $afterLabel }}</span>
</div>
</div>
使用:
{{< compare before="/img/before.jpg" after="/img/after.jpg" beforeLabel="优化前" afterLabel="优化后" >}}
视频嵌入
创建通用的视频嵌入短代码:
layouts/shortcodes/video.html:
{{ $src := .Get "src" }}
{{ $type := .Get "type" | default "video/mp4" }}
{{ $poster := .Get "poster" }}
{{ $width := .Get "width" | default "100%" }}
{{ $controls := .Get "controls" | default true }}
{{ $autoplay := .Get "autoplay" | default false }}
{{ $loop := .Get "loop" | default false }}
<video
width="{{ $width }}"
{{ if $poster }}poster="{{ $poster }}"{{ end }}
{{ if $controls }}controls{{ end }}
{{ if $autoplay }}autoplay{{ end }}
{{ if $loop }}loop{{ end }}
>
<source src="{{ $src }}" type="{{ $type }}">
您的浏览器不支持视频播放。
</video>
使用:
{{< video src="/videos/demo.mp4" poster="/img/poster.jpg" controls="true" >}}
卡片组件
创建信息卡片:
layouts/shortcodes/card.html:
{{ $title := .Get "title" }}
{{ $image := .Get "image" }}
{{ $link := .Get "link" }}
{{ $class := .Get "class" | default "" }}
<div class="card {{ $class }}">
{{ with $image }}
<div class="card-image">
<img src="{{ . }}" alt="{{ $title }}">
</div>
{{ end }}
<div class="card-content">
{{ with $title }}
<h3 class="card-title">{{ . }}</h3>
{{ end }}
<div class="card-body">
{{ .Inner | markdownify }}
</div>
{{ with $link }}
<a href="{{ . }}" class="card-link">了解更多</a>
{{ end }}
</div>
</div>
使用:
{{< card title="Hugo" image="/img/hugo-logo.png" link="https://gohugo.io" >}}
Hugo 是世界上最快的静态网站生成器。
{{< /card >}}
短代码最佳实践
命名规范
使用小写字母和连字符:
layouts/shortcodes/
├── alert.html
├── code-demo.html
├── image-gallery.html
└── video-player.html
参数验证
检查必需参数:
{{ if not (.Get "src") }}
{{ errorf "shortcode 'video' requires 'src' parameter" }}
{{ end }}
提供默认值
{{ $width := .Get "width" | default "100%" }}
{{ $class := .Get "class" | default "default-class" }}
支持 Markdown
内部内容通常应该支持 Markdown:
{{ .Inner | markdownify }}
添加 CSS 类
允许用户自定义样式:
<div class="shortcode-name {{ .Get "class" }}">
...
</div>
短代码与 Markdown 渲染
两种语法
<!-- 使用 {{< >}}:内部内容不渲染 Markdown -->
{{< highlight html >}}
**这是粗体**(不会被渲染)
{{< /highlight >}}
<!-- 使用 {{% %}}:内部内容渲染 Markdown -->
{{% note %}}
**这是粗体**(会被渲染为粗体)
{{% /note %}}
选择建议
- 纯 HTML 输出:使用
{{< >}} - 需要 Markdown 渲染:使用
{{% %}}
小结
本章介绍了 Hugo 短代码的核心知识:
- 内置短代码提供了常用的嵌入功能
- 自定义短代码可以扩展 Markdown 功能
- 短代码支持参数和内部内容
- 使用
markdownify处理 Markdown 内容 - 合理使用短代码可以保持内容的简洁性
下一章将学习 Hugo 的配置系统。