Hugo Shortcodesの作り方

Hugoでは、ちょっとしたHTMLタグを記事やテンプレートに差し込みたいと思った場合、Shortcodesという便利な機能が使えます。

例えば、次のものがあります。

  • Twitterのツイート埋め込み
  • Slideshare, Speakerdeckなどのスライドの埋め込み
  • Youtubeなどの動画埋め込み
  • Amazonアフィリエイトリンク
  • Instagramの写真
  • imgタグ
  • Adsense

Shortcodesのメリット

HTMLタグを直書きと比べて何が嬉しいかというと、次の2点が挙げられます。

  1. 変更に強い
  2. 見た目がシンプル

埋め込みURLでよくあるパターンが、各記事に手動でコードを埋め込んだはいいがちょっと変更を加えたいときに、1つ1つ直していかなければいけないというものです。

HTML直書きだと変更に対して明らかに弱いです。

一方、Shortcodesにしておけば、コードは変えずにレイアウトを後からいくらでも変更できます。サイトのテーマを変えたとしても、Shortcodesは変わりません。

このように変更に強いのはShortcodesのメリットです。

AMP化をするときも、このShortcodesが役に立ちました。 <img>タグから<amp-img>タグへの変換も、Shortcodesのレイアウトを1箇所変換すれば、Shortcodesを埋め込んだ箇所全てが変更されます。

次に、「見た目がシンプル」になるのがメリットです。

HTML直打ちだと、divタグやらimgタグやらで、どうしてもごちゃごちゃしてしまいます。 Shortcodesなら、{{% img src='/test.jpg' %}}と、シンプルに書くことができます。

Shortcodesのデメリット

逆にShortcodesのデメリットはあまり思いつきません。 強いて挙げるならば、各種Webサービスの埋め込みコードはHTML直書きに最適化されており、単純にそのまま貼り付けても使えない点です。

一度、HTMLを貼り付けて、それを自分でShortcodes用に変換してあげる必要があります。難しいことはないのですが、ちょっと面倒です。

Shortcodesの作り方

1. hoge.htmlというファイルをlayouts > shortcodesの中に作る

Hugo Shortcodesの作り方 https://farm5.staticflickr.com/4419/36881344171_f5002848c5_o.png

2. hoge.htmlの中身を書く

例えば、baseurl.htmlとして、単純に.Site.BaseURLを返すだけのShortcodesの場合の記述例は以下の通り。

baseurl.html

{{ .Site.BaseURL }}

3. Shortcodesを呼び出したいところで、Shortcodesを記述する

例えば、記事中に以下のように記述する。

Shortcodes

{{% baseurl %}}

4. hugo serverでプレビューして確認する

https://www.meganii.com/ のようにShortcodes({{% baseurl %}})が展開される。

Shortcodesの例

Speakerdeck

{{% speakerdeck XXXXXXX %}}

AMP version

{{ $id := .Get 0 }}

<amp-iframe
  width="710"
  height="596"
  allowfullscreen
  sandbox="allow-scripts allow-same-origin allow-popups allow-presentation"
  layout="responsive"
  frameborder="0"
  src="https://speakerdeck.com/player/{{$id}}">
</amp-iframe>

Amazonアフィリエイト

例えば、以下のように名前付きと、引数1つの場合を切り分けたい場合、.IsNamedParamsを利用することで処理を分けることができます。

{{% amazon 477418392X %}}
{{% amazon id="477418392X" width="100" height="100" %}}

ここでの注意点は、Go Templateの変数スコープです。一般的な変数スコープなら、以下のようにif文の中で再代入できると思ったのですが、Go Templateでは再代入・再割当ができないっぽいです。

{{ $v := "init" }}
{{ if true }}
    {{ $v := "changed" }}
{{ end }}
v: {{ $v }} {{/* => init */}}

では、どのように回避するかというと、HugoではScratchというFunctionを利用するそうです。

text/template: add support for nested variable assignment · Issue #10608 · golang/go

Scratchの使い方

  • 設定 $.Scratch.Add "Name" "Value"
  • 取得 $.Scratch.Get "Name"

改めて、AmazonアフィリエイトのShortcodesです。$jsonデータは、Data Folderのファイルを読み込んでいます。

{{ $associateId := "meganii-22" }}
{{ $json := .Site.Data.amazon }}

{{ if .IsNamedParams }}
  {{ $.Scratch.Add "amazonItemId" ( .Get "id") }}
  {{ $.Scratch.Add "amazonItemWidth" ( .Get "width") }}
  {{ $.Scratch.Add "amazonItemHeight" ( .Get "height") }}
{{ else }}
  {{ $.Scratch.Add "amazonItemId" ( .Get 0) }}
  {{ $.Scratch.Add "amazonItemWidth" "100" }}
  {{ $.Scratch.Add "amazonItemHeight" "100" }}
{{ end }}

{{ $itemId := $.Scratch.Get "amazonItemId" }}
{{ $imgWidth := $.Scratch.Get "amazonItemWidth" }}
{{ $imgHeight := $.Scratch.Get "amazonItemHeight" }}

<div>
{{ range $json }}
  {{ if eq .Item.ASIN $itemId }}
  <div class="amazon-shortcode-box">
      <div class="amazon-shortcode-inner">
        <div class="amazon-shortcode-content">
          <div class="amazon-shortcode-image">
            <a href="http://www.amazon.co.jp/exec/obidos/ASIN/{{ $itemId }}/{{ $associateId }}/" name="amazon-shortcode">
              <amp-img class="thumb" src="{{ .Item.SmallImage.URL }}" alt="{{ .title }}" width="{{ .Item.SmallImage.Width }}" height="{{ .Item.SmallImage.Height }}" layout="fixed" />
            </a>
          </div>
          <div class="amazon-shortcode-body">
            <div class="amazon-shortcode-info">
              <p class="amazon-shortcode-title">
                <a href="http://www.amazon.co.jp/exec/obidos/ASIN/{{ $itemId }}/{{ $associateId }}/" name="amazon-shortcode">{{ .Item.ItemAttributes.Title }}</a>
              </p>
              {{ with .author }}
                <p class="amazon-shortcode-author">{{ . }}</p>
              {{ end }}
              <div class="amazon-shortcode-detail">
                {{ if or ( eq .productgroup "Book") (eq .productgroup "eBooks") }}
                  <p>出版社:{{ .publisher }}</p>
                {{ else }}
                  <p>{{ .label }}</p>
                {{ end }}
                {{ with .publicationdate }}
                  <p>発売日:{{ . }}</p>
                {{ end }}
              </div>
              <p>
                <a href="http://www.amazon.co.jp/exec/obidos/ASIN/{{ $itemId }}/{{ $associateId }}/" name="backport">
                  <i class="fa fa-amazon" aria-hidden="true"></i>&nbsp;Amazonで詳細を見る
                </a>
              </p>
            </div>
          </div>
        </div>
      </div>
    </div>
  {{ end }}
{{ end }}
<div>

ぜひあなたも、HugoのShortcodesを使って、便利かつ簡潔に記述してみませんか。 おすすめのShortcodesがあったらぜひ教えてください。

みんなのGo言語【現場で使える実践テクニック】
出版社:技術評論社
著者:松木雅幸mattn藤原俊一郎中島大一牧 大輔鈴木健太稲葉貴洋
発売日: 2016/09/09

Backlinks

静的サイトジェネレータHugo
Hugo入門 静的サイトジェネレータ「Hugo」でシンプルブログサイトを構築する 静的サイトジェネレータ「Hugo」インストール 静的サイトジェネレータ「Hugo」〜公開方法〜 サイト構築 Hugoのテーマでsubmoduleを使う方法 HugoでのシンタックスハイライトにPython Pygmentsが不要となった HugoのRelated Contentを利用して関連記事を表示する gulpで画像の最適化 Hugoソースコードリーディング〜Taxonomy〜 Render Hooks for Code Blocksを利用してコードブロックにファイル名を表示する Hugoでブログカードを作成する(resources.GetRemote利用) Templates 【Hugo】Partial Templateでは複数returnを記述する早期Returnを使えない 【Hugo】images.TextでOGP画像を生成する Shortcodes Hugo Shortcodesの作り方 HugoのShortcodesを利用してAmazon紹介リンクタグを作成 HugoでAMP対応のブログカードを作る AMP対応 AMP向けのミニマルCSSフレームワーク「1BX」をHugoに導入した AMPページの最適化〜ぼくのAMPサイトがこんなに遅い訳がない〜 AMP OptimizerによるAMPのさらなる最適化 AMP Service WorkerでPrefetch Linksを実現する Data Driven Content Hugoで人気記事を表示するためJSONを返すAPIサーバを作りData-driven Contentを試してみた Tailwind CSS HugoでTailwindCSSを利用しAMP Validなページを生成する ビルド npm-run-allでローカルAPI serverとHugo serverを同時に実行する GitHub Actionsのスケジューラ実行を利用して定期的にビルドする Circle CIでHugoのビルド・デプロイを実行する コンテンツ作成 Git pre-commitフックでFrontmatterの「更新日時」を自動更新する Hugoでブログ記事一覧ページ(ブログアーカイブページ)を作成する 移行 はてなダイアリーからはてなブログ経由で独自ドメインのブログに記事を移行しました JekyllからHugoへの移行ポイント Hugoで生成した静的サイトのホスト先をさくらVPSからNetlifyに変更する 書籍
2017-12-31