Shortcodes短代码是加强模板功能的简短的、可重用的代码片段, 您可以在内容内直接嵌入短代码。
某种意义上,可以认为短代理是页面和list模板 和 基础内容文件 中的中间件.
创建定制短代码 Hugo的内建短代码覆盖了很多常见-但不是全部-的用例. 幸运的是, Hugo提供了简单创建定制短代码以满足网站需求的能力.
文件位置 为创建短代码模板, 在代码组织 的 layouts/shortcodes
目录创建新的HTML模板.
请仔细考虑文件名称,短代码名会反应文件名称, 但是不包括 .html
扩展名. 比如, layouts/shortcodes/myshortcode.html
的代码会以{{< myshortcode />}}
or {{% myshortcode /%}}
的方式被调用, 依赖于所选择参数类型。
也可以在子目录中组织短代码, 比如,在layouts/shortcodes/boxes
中. 这些短代码调用是会通过相对目录, 比如:
注意反斜线
短代码模板解析查询顺序 短代码模板的解析查询顺序简单些,仅仅查询如下两个地方:
/layouts/shortcodes/<SHORTCODE>.html
/themes/<THEME>/layouts/shortcodes/<SHORTCODE>.html
位置参数与命名参数 创建短代码可以使用下面的参数类型:
位置参数 命名参数 位置参数或者命名参数 (具有"适应性") 带有位置参数的短代码中,参数的顺序很重要。 如果短代码只有一个必填值(例如下面的youtube
短代码), 位置参数可以很好地工作,并且内容作者的键入次数更少
对于具有多个或可选参数的更复杂的布局,命名参数最有效. 命名参数虽然不那么简洁,但它们需要内容作者的更少的记忆,并且可以以任何顺序添加到短代码声明中。
对于复杂布局来说, 如果想允许用户重载默认参数值,允许两种类型的参数(比如说适应性很强的短代码)很有帮助,
访问参数 所有短代码可以通过.Get
方法访问。传递个.Get
方法的参数是一个键值(字符串)还是一个数值相应的依赖于您在访问命名参数还是位置参数.
通过名称访问参数, 请使用.Get
方法, 后面跟随引号括起的命名参数.
访问位置参数, 请使用 .Get
方法, 后面跟随一个表示位置的数值, 请注意位置参数索引从零开始:
对第二个位置, 下面这样访问:
with
方法很方便,当输出依赖于设置了某参数:
1
{{ with .Get "class"}} class="{{.}}"{{ end }}
使用.Get
方法检查参数是否设置也很有帮助。当条件依赖于某个参数的值时特别有用:
1
{{ if or (.Get "title") (.Get "alt") }} alt="{{ with .Get "alt"}}{{.}}{{else}}{{.Get "title"}}{{end}}"{{ end }}
变量 .Inner
当使用了闭合的短代码时, .Inner
变量被赋予了短代码开启和闭合括号之间的所有内容。 如果闭合短代码是必须的, 可以检查
.Inner
的长度作为短代码存在的指示.
通过 .Inner
变量定义的短代码也可以不使用内联内容、不使用闭合括号的自闭合模式来声明:
1
{{< innershortcode />}}
变量 .Params
更复杂的用例中, 短代码中变量 .Params
包含传递给短代码的参数的list. 可以使用下面逻辑访问更高范围层次的参数:
$.Params
:可以访问直接传递给短代码声明的参数(比如youtube视频ID)
$.Page.Params
页面参数的引用; 这里的 “page” 引用的是短代码声明所在的内容文件(比如, 页面内容前言设定中 shortcode_color
字段可以通过 $.Page.Params.shortcode_color
访问) $.Page.Site.Params
:站点配置文件 中定义的全局变量的引用
变量.IsNamedParams
变量 .IsNamedParams
检查短代码声明是否使用了有名参数,返回一个boolean值.
比如,创建image
短代码,接受一个命名参数src
或者第一个位置参数, 依赖于内容作者的喜好。
假设我们像下面这样调用 image
短代码:
1
{{< image src="images/my-image.jpg">}}
然后您可以包含下面代码作为短代码模板的一部分:
1
2
3
4
5
{{ if .IsNamedParams }}
<img src="{{.Get "src" }}" alt="">
{{ else }}
<img src="{{.Get 0}}" alt="">
{{ end }}
请看下面的使用.IsNamedParams
参数的样例Vimeo 短代码 .
可以使用变量 .Page
获取所有的普通的页面变量 page variables
短代码可以嵌套。在嵌入的短代码中, 可以通过.Parent
变量 访问上一级短代码上下文。这对于从根部继承常见的短代码参数很有帮助.
检查短代码是否存在 可以在页面模板中使用 .HasShortcode
参数来检查特定短代码是否在页面内使用。这个特性有时候有些帮助,比如想包含仅仅会被短代码使用的特定脚本或者样式表。
定制的短代码例子 下面是可以在/layouts/shortcodes
中创建的不同类型的短代码的例子:
单-词例子 : year
假设想使得内容文件的copyright年份维持在当前年份, 而不需要持续的检查您的markdown文件。您的目标是下面这样调用短代码:
/layouts/shortcodes/year.html
1
2
{{ now .Format "2006" }}
单一位置参数例子: youtube
嵌入的视频在markdown内容中是常见的,不过很块就会使得内容混乱。下面是Hugo内置的YouTube短代码 的使用方式:
1
{{< youtube 09jf3ow9jfw >}}
会调用/layouts/shortcodes/youtube.html
的模板:
/layouts/shortcodes/youtube.html
1
2
3
4
5
< 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 >
youtube-embed.html
1
2
3
4
5
6
7
8
< 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
短代码。
目标是像下面这样在内容文件中调用:
content-image.md
1
2
{{< img src = "/media/spf13.jpg" title = "Steve Francia" > }}
创建了短代码文件/layouts/shortcodes/img.html
,调用下面模板:
/layouts/shortcodes/img.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 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 -->
会这样呈现HTML:
img-output.html
1
2
3
4
5
6
7
< figure >
< img src = "/media/spf13.jpg" />
< figcaption >
< h4 > Steve Francia</ h4 >
</ figcaption >
</ figure >
单一的可适应行例子 : vimeo
1
2
{{< vimeo 49718712 >}}
{{< vimeo id="49718712" class="flex-video" >}}
会调用 /layouts/shortcodes/vimeo.html
的模板:
/layouts/shortcodes/vimeo.html
1
2
3
4
5
6
7
8
9
10
{{ 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 }}
HTML呈现如下:
vimeo-iframes.html
1
2
3
4
5
6
7
< 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内建的built-in shortcode
highlight-example.md
1
2
3
4
5
6
{{< highlight html > }}
< html >
< body > This HTML </ body >
</ html >
{{< / highlight > }}
highlight
短代码使用下面的代码,已经包含在Hugo中:
1
{{ .Get 0 | highlight .Inner }}
呈现的HTML输出例子代码块如下:
syntax-highlighted.html
1
2
3
4
5
< 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
的参数:
layouts/shortcodes/gallery.html
1
2
3
4
< div class = " {{ .Get "class" }} " >
{{ .Inner }}
</ div >
另外假设有img
短代码具有单一命名参数src
, 你想在gallery
或者其他短代码中使用,
由此parent定义了每个img
的上下文:
layouts/shortcodes/img.html
1
2
3
4
5
6
7
{{- $src := .Get "src" -}}
{{- with .Parent -}}
< img src = " {{ $src }} " class = " {{ .Get "class" }} -image" >
{{- else -}}
< img src = " {{ $src }} " >
{{- end }}
然后可以在内容中如下调用短代码:
1
2
3
4
5
{{< gallery class="content-gallery" >}}
{{< img src="/images/one.jpg" >}}
{{< img src="/images/two.jpg" >}}
{{< /gallery >}}
{{< img src="/images/three.jpg" >}}
输出如下的HTML. 注意头两个img
短代码继承了父级短代码gallery
调用而设置的content-gallery
的class
值,但是第三个图像仅仅有src
:
1
2
3
4
5
<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 模板函数和.Position 变量来获得有用的短代码错误信息:
1
2
3
4
{{ with .Get "name" }}
{{ else }}
{{ errorf "missing value for param 'name': %s" .Position }}
{{ end }}
当上面代码有错误时,您会在终端看见如下的ERROR
日志:
1
ERROR 2018/11/07 10:05:55 missing value for param name: "/Users/bep/dev/go/gohugoio/hugo/docs/content/en/variables/shortcodes.md:32:1"
更多短代码例子 更多短代码例子可以参考spf13.com的短代码目录 和 Hugo 文档的短代码 .
内联的短代码 从Hugo 0.52版本开始, 可以实现内联的短代码 – 就在内容文件的里面的短代码. 这对于仅仅使用一次的脚本有帮助.
这个特性默认是关闭的, 但是可以在您的站点配置中启用:
1
enableInlineShortcodes : true
1
enableInlineShortcodes = true
1
2
3
{
"enableInlineShortcodes" : true
}
由于安全原因,这个特性默认是禁用的。Hugo的模板处理所用的安全模型假设模板作者是可信任的、到那时内容文件不是,所以模板对于异常的输入信息是插入安全的。但是在很多情景下您也具有对内容的完全控制,这样打开enableInlineShortcodes = true
参数开关被认为是安全的。不过这还是需要的事项: 这允许特许的Go Text templates 在内容文件内执行。
启用以后,可以在内容文件中这样做:
1
{{ < time .inline > }}{{ now }}{{ < / time .inline > }}
上面例子会打印当前日期和是时间.
请注意内联的短代码内容是作为Go语言Text模板解析和执行的,具有和常规短代码模板相同的上下文。
也就意味这当前页面可以通过.Page.Title
等访问。这也意味着没有"嵌套内联模板"的概念.
相同的内联短代码模板也可以在相同的内容文件的后面重用,如果有必要使用不同的参数,使用自我闭合的模式.