创建自定义短代码
短代码是将模板整合到小型、可重用的代码片段中的方式,您可以直接嵌入到内容中。
创建自定义短代码
Hugo的内置短代码覆盖了许多常见的使用情况,但并不是全部。幸运的是,Hugo提供了创建自定义短代码以满足网站需求的便利能力。
文件位置
要创建一个短代码,请将HTML模板放置在源组织的layouts/shortcodes
目录中。请仔细考虑文件名,因为短代码名称将与文件名称相同,但不包含.html
扩展名。例如,layouts/shortcodes/myshortcode.html
将使用{{< myshortcode />}}
或{{% myshortcode /%}}
进行调用。
您可以将短代码组织在子目录中,例如layouts/shortcodes/boxes
。然后可以使用相对路径访问这些短代码,例如:
{{< boxes/square />}}
请注意正斜杠。
短代码模板的查找顺序
短代码模板有一个简单的查找顺序:
/layouts/shortcodes/<SHORTCODE>.html
/themes/<THEME>/layouts/shortcodes/<SHORTCODE>.html
位置参数与命名参数
您可以使用以下类型的参数来创建短代码:
- 位置参数
- 命名参数
- 位置参数和命名参数(即"灵活")
在带有位置参数的短代码中,参数的顺序很重要。如果一个短代码有一个必需的值(例如下面的youtube
短代码),位置参数非常有效,并且需要内容作者键入较少的字符。
对于具有多个或可选参数的更复杂布局,命名参数的效果最好。虽然更繁琐,但命名参数要求内容作者记忆较少,并且可以按任意顺序在短代码声明中添加。
同时允许这两种类型的参数(即"灵活"短代码)对于复杂的布局非常有用,其中您希望设置可以由用户轻松覆盖的默认值。
访问参数
可以通过.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不为空
{{ end }}
通过使用自关闭语法,通过使用.Inner
变量声明的具有内容的短代码也可以在没有内容和闭合标签的情况下声明:
{{< innershortcode />}}
.Params
短代码中的.Params
变量包含传递给短代码的参数列表,以进行更复杂的使用。您还可以使用以下逻辑访问更高级的参数:
$.Params
- 这些是直接传递到短代码声明中的参数(例如,YouTube视频ID)
$.Page.Params
- 引用页面参数;在这种情况下,“page"是指包含短代码声明的内容文件(例如,可以通过
$.Page.Params.shortcode_color
访问内容前置的shortcode_color
字段)。 $.Page.Site.Params
- 引用全局变量,如在您的[站点配置文件][config]中定义的。
.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 }}
请参阅下面的[示例Vimeo短代码][vimeoexample]以了解.IsNamedParams
的用法。
您还可以使用变量.Page
来访问所有常规的[页面变量][pagevars]。
短代码也支持嵌套。在嵌套短代码中,您可以使用[.Parent
变量][shortcodesvars]访问父短代码上下文。这对于从根短代码继承常用短代码参数非常有用。
检查是否存在
您可以通过在页面模板中调用.HasShortcode
来检查页面上是否使用了特定的短代码,其中提供短代码的名称。当您希望仅在使用该短代码时在标题中包含特定的脚本或样式时,这通常很有用。
自定义短代码示例
以下是您可以通过在/layouts/shortcodes
中创建短代码模板文件来创建的不同类型的短代码示例。
单词示例:year
假设您希望在内容文件中保持版权年份的最新状态,而无需不断检查Markdown。您的目标是能够按以下方式调用该短代码:
{{< year >}}
{{ now.Format "2006" }}
单位置示例:youtube
内嵌视频是Markdown内容中常见的补充,但可能会变得难以看。下面是[Hugo的内置YouTube短代码][youtubeshortcode]的代码:
{{< youtube 09jf3ow9jfw >}}
将加载/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>
<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
短代码][figure]。您的目标是在内容文件中按以下方式调用该短代码:
{{< img src="/media/spf13.jpg" title="Steve Francia" >}}
您已在/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 -->
将呈现为:
<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
中的模板:
{{ 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 }}
将呈现为:
<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 html >}}
<html>
<body> This HTML </body>
</html>
{{< /highlight >}}
highlight
短代码的模板使用以下代码,该代码已包含在Hugo中:
{{ .Get 0 | highlight .Inner }}
HTML示例代码块的呈现输出将如下所示:
<div class="highlight" style="background: #272822"><pre style="line-height: 125%"><span style="color: #f92672"><html></span>
<span style="color: #f92672"><body></span> This HTML <span style="color: #f92672"></body></span>
<span style="color: #f92672"></html></span>
</pre></div>
嵌套短代码:图像库
Hugo的[.Parent
短代码变量][parent]提供了在短代码在父短代码上下文中调用时访问父短代码上下文的能力。这为常见短代码参数的继承提供了一个模型。
以下示例有些牵强,但演示了该概念。假设您有一个gallery
短代码,该短代码期望一个命名为class
的参数:
<div class="{{ .Get "class" }}">
{{ .Inner }}
</div>
您还有一个img
短代码,其中只有一个命名为src
的参数,您想要在gallery
和其他短代码中调用该短代码,从而由父级定义每个img
的上下文:
{{- $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
中设置的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模�