Hugo 自定义 Shortcodes 模板

Hugo 自带 Shortcodes 功能,除了内置的一些常用 shortcode,我们也可以根据需求自己编写 Shortcodes 模板。

本文通过一个简单的例子(创建一个给文本增加额外样式的 shortcode),来演示一下自定义 Shortcodes 模板的大致流程。

首先,我们在 themes/your-theme/layouts/ 下新建一个 shortcodes 目录,这个目录就是用来存放 shortcode 模板的。跟 Hugo 的其他模板文件一样,shortcode 模板也可以有层级,比如 shortcodes/media/ 下面可以有 tweetyoutube 两个目录,分别用来放置调用 twitter 推文和 YouTube 视频的 shortcode 模板。调用时只需要把目录层级一块写上就好,比如

{{< media/youtube e6Ft9xhsgob >}}
{{< media/tweet 82319053876012 >}}

本文例子比较简单,所以直接放到 shortcodes 目录下,调用时直接写上模板名称就行了。

本文想要实现的小功能非常简单,给文章内的某个词汇或者句子添加额外的样式,比如颜色、背景、字体大小等。

具体到例子,给「不负韶华,我们都是追梦人。」这句话中的「追梦人」三个字加上颜色、背景色、并把大小设为 1.2em且加粗显示

总的来说,Hugo 有两种方式来实现这个 shortcode,这两种方式各有适合的场景,但是也不是那么分明,两者可以互换的,也可以混合着使用。

我们先看第一种:

对于文章本身我们可以这样写:

「不负韶华,我们都是{{< css style="color:#00f3ff; background:#3a13b1; font-size:1.2em; font-weight:bold;" >}}追梦人{{< /css >}}。」

再看下另外一种,可以这样写:

「不负韶华,我们都是{{< textstyle "#00f3ff" "#3a13b1" 1.2em bold >}}追梦人{{< /textstyle >}}。」

上面这两种写法,可以有两种不同的 shortcode 模板语句来实现,我们先看第一种:

我们在 shortcodes 目录下面新建一个 css.html 文件,这个就是我们的模板文件,我们要实现的功能的代码就放在这个文件里。其实跟 Hugo 的其他模板都一样的,无非就是 Go template 语句,逻辑判断什么的,第一种的代码如下:

<span style="{{ .Get "style" | safeCSS }}">
{{- .Inner -}}
</span>

而第二种,同样,我们创建好模板文件 textstyle.html,实现语句稍微有些差别,具体代码如下:

<span style="{{ with .Get 0 }}color:{{ . }};{{ end }}{{ with .Get 1 }}background:{{ . }};{{ end }}{{ with .Get 2 }}font-size:{{ . }};{{ end }}{{ with .Get 3 }}font-weight:{{ . }};{{ end }}">
{{- .Inner -}}
</span>

而最终它们实现的前端效果肯定都是一样的:

第一种如下:

「不负韶华,我们都是追梦人。」

第二种如下:

「不负韶华,我们都是追梦人。」

它们的 style 是一模一样的:

element.style {
  color: #00f3ff;
  background: #3a13b1;
  font-size: 1.2em;
  font-weight: bold;
}

【注意事项:】

1、对于第一种,因为直接引用的一长串样式,其中包含 ;(英文分号),而 Go template 认为这个是不安全的,会过滤掉,最终显示 ZgotmplZ 这么个奇怪的代码。我们可以通过加上 safeCSS 来避免。

2、可以看到我们是用 .Get 来获取 shortcode 的参数的,参数的位置是从 0 开始计的,你懂的。

3、对于第二种方式,如果 shortcode 的参数包含特殊符号,比如本例中的 # 号,那么这个参数需要用 " 包裹起来。

4、还是第二种方式,如果我们不需要这 4 个额外的样式,只想要改变个背景颜色呢?

因为语句的限制,我们必须得提供相应数量的参数,否则因为样式是写死的,参数不够的话,会篡位导致错误。当然可以加更多的判断语句,但是会过于复杂,shortcode 本来就是用短而精的代码实现小而精的功能,所以个人觉得还是提供 4 个参数,只是把不需要的参数写成 inherit 就行了。假如只想要改变背景颜色,我们可以写成下面这样:

「不负韶华,我们都是{{< textstyle inherit "#3a13b1" inherit inherit >}}追梦人{{< /textstyle >}}。」

至于顺序,毕竟是 shortcode,用的不多,只能强记因为 shortcode 的应用场景就是这样。比如我们这个例子,可以记成「前、后、大小、胖瘦」,也就是对应着「颜色」「背景色」「字体大小」「字体粗细」😄。

好了,大致就是如此,熟悉了方法,我们就可以创建更复杂更强大的 Shortcodes 来实现一些特殊功能。