来写一些好玩的 Hugo 短代码吧

博客装修 2022年11月14日 18:02
💡
请注意,由于博主已更换博客系统为 “Ghost”,以下代码已无法正常显示。 ——2023年12月22日18:10

Hugo短代码

由Hugo官方的文档可知,简码是内容文件中调用内置或自定义模板的简单代码段。那为什么会用到这东西呢🤔?因为:

💡
虽然Markdown的内容格式简单,但有时会达不到创作者的要求。通常,内容作者被迫将原始HTML(例如视频)添加到Markdown内容中。Hugo认为这与 Markdown语法的简单性相矛盾,比如<iframe>之类的标签。Hugo创造了短代码(shortcodes)来规避这些限制。

你会发现,上面这段文字被框起来了🎉,这就是Hugo短代码的实际运用~

短代码是内容文件中的简单片段,Hugo 将使用预定义的模板呈现该片段。请注意,短代码在模板文件中不起作用。如果需要短代码提供的插入功能类型,但在模板中,那很可能需要一个部分模板。除了更简洁的Markdown之外,短代码可以随时更新以反映新的类、技术或标准。在网站生成时,Hugo短代码将轻松合并更改。避免可能复杂的搜索和替换操作。

编写

在Markdown文件中,Hugo短代码通过{{</* shortcodename parameters */>}}的形式引用。前一个单词shortcodename为短代码名称,后一个单词parameters为参数,且排除第一个单词外都是参数,中间使用空格隔开。如果需要多个参数的传递,那么需要使用name="value"的形式传值。

💡
在Hugo中使用短代码,需要在在Hugo根目录下的./layouts/shortcodes/创建shortcodename.html文件,shortcodename为你短代码的名字。

语法

这里先写一些Hugo的简单语法😙,如:

{{ index .Params 0 }}

这句代码表达的意思为获取短代码中的第一个参数,如果是{{ index .Params 1 }}代表第二个,以此轮推。

{{ .Get "text1" }}

此代码表达为获取参数名为text1的参数,如果引用代码为{{</* myshortscode text="文本" */>}},那么传入的参数为“文本”二字。

传入日期需要使用{{/* .Date.Format ( default "2006-01-02") */}},后面为可以格式化的日期样式。

使用{{ /*with .Site.Params.footer.customText */}}语句可以引用站点配置文件中定义的变量值。如{{ /*with .Site.Params.sidebar.subtitle */}}此语句返回为:吕楪在记录自己的生活

分享

在Github与Google一通搜索😵‍💫后收集了很多短代码,连带着自己也照着写了几个😊。

高亮

样式:

{{< mark text="这是一个重点标记" >}}

创建mark.html文件,其中内容编写:

<mark>{{ .Get "text" }}</mark>

这样一个简单的短代码便实现啦,但默认的高亮为荧光黄色,看起来有点刺眼,那么可以在./assets/scss/custom.css中增加mark标记的样式🤭。

{{< notice notice-warning >}}
注意:./assets/scss/custom.css为我使用主题的自定义css文件,其他主题可能不相同。
{{< /notice >}}

mark{
    background: hsla(332, 81%, 58%, 0.879);
}

使用:

{{</* mark text="这是一个重点标记" */>}}

但这个颜色也不好看诶🥲。

缩写

样式:

{{< abbr title="这里有着非常非常非常非常非常非常非常非常长的缩写内容~" text="缩写的文本" >}}

这时,将鼠标放在缩写的文本上方时,会自动浮现出被缩写的内容。

创建abbr.html文件,其中内容编写:

<abbr title="{{ .Get "title" }}">{{ .Get "text" }}</abbr>

使用:

{{</* abbr title="这里有着非常非常非常非常非常非常非常非常长的缩写内容~" text="缩写的文本" */>}}

蛮好玩的样子😙!

文本位置

样式:

{{< align center "文字居中" >}}

会发现上面的文本在文章中心。

创建align.html文件,其中内容编写:

<p style="text-align:{{ index .Params 0 }}">{{ index .Params 1 | markdownify }}</p>

使用:

{{</* align center "文字居中" */>}}

理解起来也非常简单😘,首先align.html内容为一段html5编码,p标签为段落,我们要实现的自由变动文本位置需要使用css样式text-align,这里能用的参数有:center、left、right。

{{ index .Params 0 }}代表读取短代码的第一个参数center{{ index .Params 1 | markdownify }}代表读取短代码中第二个参数,至于markdownify代表通过Markdown处理器运行提供的字符串。markdownifyHugo V0.93版本提供的新功能,旧版本不适用哦。

块引用

样式:

{{< blockquote author="电影" link="https://irithys.com" title="《寻梦环游记》" >}}
死亡不是一切的终点,遗忘才是
{{< /blockquote >}}

创建blockquote.html文件,拷贝以下内容。

<!-- reset scratch variables at the start -->
{{ $.Scratch.Set "bl_author" false }}
{{ $.Scratch.Set "bl_source" false }}
{{ $.Scratch.Set "bl_link" false }}
{{ $.Scratch.Set "bl_title" false }}

{{ if .IsNamedParams }}
  {{ $.Scratch.Set "bl_author" (.Get "author") }}
  {{ $.Scratch.Set "bl_source" (.Get "source") }}
  {{ $.Scratch.Set "bl_link" (.Get "link") }}
  {{ $.Scratch.Set "bl_title" (.Get "title") }}
{{ else }}
  <!-- for the positional version if any -->
{{ end }}

<!-- if title is not set explicitly then we need to beautify the link
     if length of link is more than 32 chars, we will cut it off by 32 and
     then drop everything after the last / if any and put it in into title -->

{{ with $.Scratch.Get "bl_title" }}
  <!-- do nothing -->
{{ else }}
  {{ with $.Scratch.Get "bl_link" }}    <!-- if link is given -->
    {{ range last 1 (split ($.Scratch.Get "bl_link" ) "://") }}  <!-- split by :// and then only take the items after it to remove protocol:// -->
      {{ $.Scratch.Set "title_without_protocol" . }}
    {{ end }}
    {{ range last 1 (split ($.Scratch.Get "title_without_protocol" ) "www.")  }} <!-- also remove the www. at the start if any. we are using a second split because all URLS may not start with it -->
      {{ $.Scratch.Set "title_without_protocol" . }}
    {{ end }}
    {{ $.Scratch.Set "bl_title" ($.Scratch.Get "title_without_protocol") }}

    <!-- if link is longer than 32 bytes we should trim it -->
    {{ if (gt (len ($.Scratch.Get "title_without_protocol") ) 32) }}
      {{ $title := (slicestr ($.Scratch.Get "title_without_protocol") 0 32) }}   <!-- get the first 32 characters of title_without_protocol -->
      {{ $split_by_fw_slash := split $title "/" }}   <!-- now split on / because we want to stop after the last forward slash -->
      {{ $count := (sub (len $split_by_fw_slash) 1) }}   <!-- we want everything but the last part so we adjust the count accordingly -->

      {{ $.Scratch.Set "tempstring" "" }}   <!-- temp variable to hold the concatinated string -->
      {{ range first $count $split_by_fw_slash  }}  <!-- loop through all parts except last and concat them (add / between halves) -->
        {{ $.Scratch.Set "tempstring" ( . | printf "%s%s/" ($.Scratch.Get "tempstring") | printf "%s" ) }}
      {{ end }}
      {{ $.Scratch.Set "bl_title" ( printf "%s..." ($.Scratch.Get "tempstring") | printf "%s" ) }}
    {{ end }}
  {{ end }}
{{ end }}

<blockquote>
  <p>{{ .Inner | markdownify }}</p>
  <footer style="text-align:right">
    <strong>{{ with $.Scratch.Get "bl_author" }}{{ . }}{{ end }}</strong>
    {{ with $.Scratch.Get "bl_source" }}
      <cite>{{ . }}</cite>
    {{ else }}
      {{ with $.Scratch.Get "bl_link" }}
        <cite>
          <a href="{{ . }}" title="{{ . }}" rel="noopener noreferrer">{{ $.Scratch.Get "bl_title" }}</a> <!-- can't have new lines here -->
        </cite>
      {{ else }}
        {{ with $.Scratch.Get "bl_title" }}
          <cite>
            {{ $.Scratch.Get "bl_title" }}</a>
          </cite>
        {{ end }}
      {{ end }}
    {{ end }}
  </footer>
</blockquote>

使用:

{{</* blockquote author="电影" link="https://irithys.com" title="《寻梦环游记》" */>}}
死亡不是一切的终点,遗忘才是
{{</* /blockquote */>}}

隐藏

样式:

{{< detail "点下我呀🎁" >}}
对看到这行文字的人报以深切的祝福🥰!
{{< /detail >}}

创建detail.html文件,拷贝其中内容:

<details>
    <summary>{{ (.Get 0) | markdownify }}</summary>
    {{ .Inner | markdownify }}
</details>

使用:

{{</* detail "点下我呀🎁" */>}}
对看到这行文字的人报以深切的祝福!🥰
{{</* /detail */>}}

标签

这里的标签非常好看!文章第一章节便使用了这个标签。源文件来自@martignoni,但颜色过重,我使用了@荷戟独彷徨的修改版本~

此标签有4个样式~

样式一,警告:
{{< notice notice-warning >}}
警告!这个标签太好看了,我忍不住分享。
{{< /notice >}}

样式二,信息:
{{< notice notice-info >}}
明确的爱,直接的厌恶,真诚的喜欢。站在太阳下的坦荡,大声无愧地称赞自己。
{{< /notice >}}

样式三,贴条:
{{< notice notice-tip >}}
遇到一些需要做提示性语句的位置,可以贴个条。
{{< /notice >}}

样式四,注释:
{{< notice notice-note >}}
我想要的不是解释,而是注释。
{{< /notice >}}

创建notice.html文件,拷贝以下内容:

{{- $noticeType := .Get 0 -}}

{{- $raw := (markdownify .Inner | chomp) -}}

{{- $block := findRE "(?is)^<(?:address|article|aside|blockquote|canvas|dd|div|dl|dt|fieldset|figcaption|figure|footer|form|h(?:1|2|3|4|5|6)|header|hgroup|hr|li|main|nav|noscript|ol|output|p|pre|section|table|tfoot|ul|video)\\b" $raw 1 -}}

{{ $icon := (replace (index $.Site.Data.SVG $noticeType) "icon" "icon notice-icon") }}
<div class="notice {{ $noticeType }}" {{ if len .Params | eq 2 }} id="{{ .Get 1 }}" {{ end }}>
    <div class="notice-title">{{ $icon | safeHTML }}</div>
    {{- if or $block (not $raw) }}{{ $raw }}{{ else }}<p>{{ $raw }}</p>{{ end -}}
</div>

/assets/scss/custom.scss中新加入以下样式:

.notice {
  position:relative;
  padding: 1em 1em 1em 2.5em;
  margin-bottom: 1em;
  border-radius: 4px;
  p:last-child {
      margin-bottom: 0;
  }
  .notice-title {
      position: absolute;
      left: 0.8em;
      .notice-icon {
          width: 1.2em;
          height: 1.2em;
      }
  }
  &.notice-warning {
      background: hsla(0, 65%, 65%, 0.15);
      border-left: 5px solid hsl(0, 65%, 65%);
      .notice-title {
          color: hsl(0, 65%, 65%);
      }
  }
  &.notice-info {
      background: hsla(30, 80%, 70%, 0.15);
      border-left: 5px solid hsl(30, 80%, 70%);
      .notice-title {
          color: hsl(30, 80%, 70%);
      }
  }
  &.notice-note {
      background: hsla(200, 65%, 65%, 0.15);
      border-left: 5px solid hsl(200, 65%, 65%);
      .notice-title {
          color: hsl(200, 65%, 65%);
      }
  }
  &.notice-tip {
      background: hsla(140, 65%, 65%, 0.15);
      border-left: 5px solid hsl(140, 65%, 65%);
      .notice-title {
          color: hsl(140, 65%, 65%);
      }
  }
}

[data-theme="dark"] .notice {
  &.notice-warning {
      background: hsla(0, 25%, 35%, 0.15);
      border-left: 5px solid hsl(0, 25%, 35%);
      .notice-title {
          color: hsl(0, 25%, 35%);
      }
  }
  &.notice-info {
      background: hsla(30, 25%, 35%, 0.15);
      border-left: 5px solid hsl(30, 25%, 35%);
      .notice-title {
          color: hsl(30, 25%, 35%);
      }
  }
  &.notice-note {
      background: hsla(200, 25%, 35%, 0.15);
      border-left: 5px solid hsl(200, 25%, 35%);
      .notice-title {
          color: hsl(200, 25%, 35%);
      }
  }
  &.notice-tip {
      background: hsla(140, 25%, 35%, 0.15);
      border-left: 5px solid hsl(140, 25%, 35%);
      .notice-title {
          color: hsl(140, 25%, 35%);
      }
  }
}

文件中的[data-theme="dark"]为暗色模式下的css样式,虽然我主题带有暗色模式,但没有用。推测应该需要在variables.scss中定义变量然后引用。但应该蛮少人在我博客中使用暗色模式的吧,就先这样用吧。

之后,在./data/目录下新建SVG.toml文件,拷贝以下内容:

notice-warning = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 576 512" fill="hsl(0, 65%, 65%)"><path d="M256 8C119 8 8 119 8 256s111 248 248 248 248-111 248-248S393 8 256 8zM124 296c-6.6.0-12-5.4-12-12v-56c0-6.6 5.4-12 12-12h264c6.6.0 12 5.4 12 12v56c0 6.6-5.4 12-12 12H124z"/></svg>'
notice-info = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512" fill="hsl(30, 80%, 70%)"><path d="M256 8a248 248 0 100 496 248 248 0 000-496zm0 110a42 42 0 110 84 42 42 0 010-84zm56 254c0 7-5 12-12 12h-88c-7 0-12-5-12-12v-24c0-7 5-12 12-12h12v-64h-12c-7 0-12-5-12-12v-24c0-7 5-12 12-12h64c7 0 12 5 12 12v100h12c7 0 12 5 12 12v24z"/></svg>'
notice-note = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512" fill="hsl(200, 65%, 65%)"><path d="M504 256a248 248 0 11-496 0 248 248 0 01496 0zm-248 50a46 46 0 100 92 46 46 0 000-92zm-44-165l8 136c0 6 5 11 12 11h48c7 0 12-5 12-11l8-136c0-7-5-13-12-13h-64c-7 0-12 6-12 13z"/></svg>'
notice-tip = '<svg xmlns="http://www.w3.org/2000/svg" class="icon" viewBox="0 0 512 512" fill="hsl(140, 65%, 65%)"><path d="M504 256a248 248 0 11-496 0 248 248 0 01496 0zM227 387l184-184c7-6 7-16 0-22l-22-23c-7-6-17-6-23 0L216 308l-70-70c-6-6-16-6-23 0l-22 23c-7 6-7 16 0 22l104 104c6 7 16 7 22 0z"/></svg>'

此文件中定义的4个变量为svg矢量图,如果想要用其他的图片也可以换成其他的。

注意:如果在/assets/scss/custom.scss中定义的css样式不起作用,也就是说图标为黑色状态,那么需要在SVG标签中写入fill="hsl(0, 65%, 65%)"之类的颜色标签,此内容和css在定义中定义的颜色相同。

使用:

{{</* notice notice-warning */>}}
警告!这个标签太好看了,我忍不住分享。
{{</* /notice */>}}

这是第一个标签,将notice-warning分别修改为notice-notenotice-infonotice-tip就可以得到其他三个不同样式的标签啦😛。

音乐

样式:

{{< music id="557578993" type="song" server="netease" >}}

首先,引用外部链接需要关闭Hugo的安全模式(必须):

打开根目录的config.yaml文件,修改以下内容:

markup:
    goldmark:
        renderer:
            unsafe: true

当然,如果配置文件为config.toml,则是这种修改方式:

[markup.goldmark.renderer]
unsafe= true
此步骤设置为true,markdown中就可以使用html5标签啦。

新建music.html文件夹,拷贝以下内容:

<!-- require APlayer -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.css">
<style type="text/css">.dark-theme .aplayer{background:#212121}.dark-theme .aplayer.aplayer-withlist .aplayer-info{border-bottom-color:#5c5c5c}.dark-theme .aplayer.aplayer-fixed .aplayer-list{border-color:#5c5c5c}.dark-theme .aplayer .aplayer-body{background-color:#212121}.dark-theme .aplayer .aplayer-info{border-top-color:#212121}.dark-theme .aplayer .aplayer-info .aplayer-music .aplayer-title{color:#fff}.dark-theme .aplayer .aplayer-info .aplayer-music .aplayer-author{color:#fff}.dark-theme .aplayer .aplayer-info .aplayer-controller .aplayer-time{color:#eee}.dark-theme .aplayer .aplayer-info .aplayer-controller .aplayer-time .aplayer-icon path{fill:#eee}.dark-theme .aplayer .aplayer-list{background-color:#212121}.dark-theme .aplayer .aplayer-list::-webkit-scrollbar-thumb{background-color:#999}.dark-theme .aplayer .aplayer-list::-webkit-scrollbar-thumb:hover{background-color:#bbb}.dark-theme .aplayer .aplayer-list li{color:#fff;border-top-color:#666}.dark-theme .aplayer .aplayer-list li:hover{background:#4e4e4e}.dark-theme .aplayer .aplayer-list li.aplayer-list-light{background:#6c6c6c}.dark-theme .aplayer .aplayer-list li .aplayer-list-index{color:#ddd}.dark-theme .aplayer .aplayer-list li .aplayer-list-author{color:#ddd}.dark-theme .aplayer .aplayer-lrc{text-shadow:-1px -1px 0 #666}.dark-theme .aplayer .aplayer-lrc:before{background:-moz-linear-gradient(top, #212121 0%, rgba(33,33,33,0) 100%);background:-webkit-linear-gradient(top, #212121 0%, rgba(33,33,33,0) 100%);background:linear-gradient(to bottom, #212121 0%, rgba(33,33,33,0) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#212121', endColorstr='#00212121',GradientType=0 )}.dark-theme .aplayer .aplayer-lrc:after{background:-moz-linear-gradient(top, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);background:-webkit-linear-gradient(top, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);background:linear-gradient(to bottom, rgba(33,33,33,0) 0%, rgba(33,33,33,0.8) 100%);filter:progid:DXImageTransform.Microsoft.gradient( startColorstr='#00212121', endColorstr='#cc212121',GradientType=0 )}.dark-theme .aplayer .aplayer-lrc p{color:#fff}.dark-theme .aplayer .aplayer-miniswitcher{background:#484848}.dark-theme .aplayer .aplayer-miniswitcher .aplayer-icon path{fill:#eee}</style>
<script src="https://cdn.jsdelivr.net/npm/aplayer/dist/APlayer.min.js"></script>
<!-- require MetingJS -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/Meting.min.js"></script>

<!-- 注意!!我因为APlayer与meting-js都是以插件形式引入的,所以不需要写上面这些 -->
{{ if .IsNamedParams }}
    <meting-js
      id="{{ .Get "id" }}"
      server="{{ .Get "server" }}"
      type="{{ .Get "type" }}"
      fixed="{{ if .Get "fixed" }}{{ .Get "fixed" }}{{ else }}false{{ end }}"
      mini="{{ if .Get "mini" }}{{ .Get "mini" }}{{ else }}false{{ end }}"
      autoplay="{{ if .Get "autoplay" }}{{ .Get "autoplay" }}{{ else }}false{{ end }}"
      loop="{{ if .Get "loop" }}{{ .Get "loop" }}{{ else }}none{{ end }}"
      theme="{{ if .Get "autoplay" }}{{ .Get "autoplay" }}{{ else }}#255579{{ end }}"
      volume="{{ if .Get "volume" }}{{ .Get "volume" }}{{ else }}0.6{{ end }}"
      prelosd="{{ if .Get "prelosd" }}{{ .Get "prelosd" }}{{ else }}auto{{ end }}"
      mutex="{{ if .Get "mutex" }}{{ .Get "mutex" }}{{ else }}true{{ end }}"
      list-folded="{{ if .Get "list-folded" }}{{ .Get "list-folded" }}{{ else }}true{{ end }}">
    </meting-js>
{{ end }}

使用:

{{</* music id="557578993" type="song" server="netease" */>}}

此处的id为音乐的网址id,如我上面引用的音乐,地址为https://music.163.com/#/song?id=557578993server代表用的哪家的服务,netease代表网易,还可以使用有腾讯tencent,酷狗kugou,百度baidu

长毛象

样式:

{{< mastodon status="109336902159860386" >}}

新建mastodon.html文件,拷贝以下内容:

{{ .Page.Scratch.Set "include_mastodon" true }}
{{ $server := .Get "server" | default "im.irithys.com" }}
{{ $user := .Get "user" | default "thy" }}
{{ $width := .Get "width" | default "100%" }}
{{ $height := .Get "height" | default "auto"}}
{{ $status := .Get "status" | default "false" }}

{{ if eq ($status) "false" }}
{{ else }}
<iframe src= "https://{{ $server }}/@{{ $user }}/{{ $status }}/embed" class="mastodon-embed" style="max-width: 100%; border: 0" width="{{ $width }}" height="{{ $height }}" allowfullscreen="allowfullscreen"></iframe><script src="https://{{ $server }}/embed.js" async="async"></script>
{{ end }}

这里我在上方预先定义了一些默认的常量,如serveruser,这是因为如果是引用自己的话,每次都传一次也太呆了吧。所以如果其他毛象站的朋友们使用,需要先修改server为自己的服务器,user为自己的用户名

使用:

{{</* mastodon status="109336902159860386" */>}}

只需要将嘟文id传入就好啦😙~

哔站

样式:

{{< bilibili BV1NF411J7JH >}}

创建bilibili.html文件,拷贝以下内容:

{{ $vid := (.Get 0) }}
{{ $videopage := default 1 (.Get 1) }}
{{ $basicQuery := querify "page" $videopage "high_quality" 1 "as_wide" 1 }}
{{ $videoQuery := "" }}

{{ if strings.HasPrefix (lower $vid) "av" }}
    {{ $videoQuery = querify "aid" (strings.TrimPrefix "av" (lower $vid)) }}
{{ else if strings.HasPrefix (lower $vid) "bv" }}
    {{ $videoQuery = querify "bvid" $vid }}
{{ else }}
    <p>Bilibili 视频av号或BV号错误!请检查视频av号或BV号是否正确</p>
    <p>当前视频av或BV号:{{ $vid }},视频分P:{{ $videopage }}</p>
{{ end }}

<div class="video-wrapper">
    <iframe src="https://player.bilibili.com/player.html?{{ $basicQuery | safeURL }}&{{ $videoQuery | safeURL }}"
            scrolling="no"
            frameborder="no"
            framespacing="0"
            allowfullscreen="true"
    >
    </iframe>
</div>

使用:

{{</* bilibili BV1NF411J7JH */>}}

蛮好玩的,B站除了一些需要版权的视频之外,都可以引用哦。

网易云

样式:

{{< netease 557578993 0 >}}

这其实是网易云自带的嵌入,略作修改后就能拿过来用啦。

新建netease.html文件,拷贝以下内容:

<iframe frameborder="no" border="0" marginwidth="0" marginheight="0" width=100% height=86 src="//music.163.com/outchain/player?type=2&id={{ index .Params 0 }}&auto={{ index .Params 1 }}&height=66"></iframe>

使用:

{{</* netease 557578993 0 */>}}

输入的第一个参数为歌曲的id,第二个参数代表是否自动播放,1为自动播放,0为手动播放。

完结

分享完毕😊,在之后我遇到新的Hugo短代码再继续更新此文章😋~我发现国内好多网站都已经不提供嵌入代码了呀,虽然是互联网但是没有一点开放的态度呢🤔。

标签

吕楪

博主.本博客的所有者,一切的开始。