技術書の紹介をする際も、カエレバのようなリンクビルダーを利用してきましたが、重い腰を上げてHugoのshortcodesData-driven Contentで対応しました。

使用方法

{{% amazon 477418392X %}}と記述することで、以下の結果を得ることができます。

Shortcodesを利用するメリット

  1. 紹介リンクを生成して貼り付ける必要がなくなった
  2. Markdownの文書中にHTMLリンクを埋め込まなくてよくなったので可視性が上がった
  3. Amazon紹介のリンクのデザインを変更する場合、Shortcodesとcssを変更することで一括変更できるようになった

Amazon紹介リンクをhtmlで埋め込むと、変更したくなった場合は1つ1つ手で直していかなければいけません。Shortcodesにしておけば、テンプレートとCSSを変えることで簡単にデザインを変更することができます。

Shortcodes amazon.html

{{ $associateId := "YOUR_ASSOCIATE_ID" }}
{{ $itemId := index .Params 0 }}
{{ $json := getJSON "https://yourapi.com/?itemid=" $itemId }}

<div class="amazon-shortcode-box">
  <div class="amazon-shortcode-image">
    <a href="http://www.amazon.co.jp/exec/obidos/ASIN/{{ $itemId }}/{{ $associateId }}/" name="amazon-shortcode" target="\_blank">
      <img src="{{ $json.image_url }}" alt="{{ $json.title }}" />
    </a>
  </div>
  <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" target="\_blank">
        {{ $json.title }}
      </a>
    </p>
    {{ with $json.author }}
      <p class="amazon-shortcode-author">{{ . }}</p>
    {{ end }}
    <div class="amazon-shortcode-detail">
      {{ if or ( eq $json.productgroup "Book") (eq $json.productgroup "eBooks") }}
        <p>出版社:{{ $json.publisher }}</p>
      {{ else }}
        <p>{{ $json.label }}</p>
      {{ end }}
      {{ with $json.publicationdate }}
        <p>発売日:{{ . }}</p>
      {{ end }}
    </div>
    <p>
      <a href="http://www.amazon.co.jp/exec/obidos/ASIN/{{ $itemId }}/{{ $associateId }}/" name="backport" target="\_blank">
        <i class="fa fa-amazon" aria-hidden="true"></i>&nbsp;Amazonで詳細を見る
      </a>
    </p>
  </div>
  <br style="clear: both;"/>
</div>

Data-driven Content

getJSONの取得先は自前のAPIサーバです。AmazonのItem Idを渡し、Amazon Product Advertising APIを利用して情報を取ってきます。

amazon.html

{{ $itemId := index .Params 0 }}
{{ $json := getJSON "https://yourapi.com/?itemid=" $itemId }}

getJSONで指定したURIにGETリクエストを送って、jsonを取得します。取得したデータは、デフォルトだと$TMP/hugoに格納されます。私は、config.ymlでcacheDir: cacheと指定しているため、cacheディレクトリにどんどん溜まっていきます。

APIサーバのレスポンスを待つため、一気にAmazonリンクを生成しようとするとどうしてもタイムアウトを起こしてhugo生成がエラーになります。これは、Amazon Product Advertising APIの仕様で連続アクセスが禁止されているため、APIサーバ側でエラーになってしまうからです。

今の運用は、

  1. VSCodeでMarkdown編集
  2. hugo serverでプレビュー実施
  3. {{ amazon ITEMID }}を1件ずつ処理

と1つずつ確認しながら実施することで回避しています。一度でも正常に生成できれば、cacheディレクトリにキャッシュが作成されるため、以降はエラーが発生しなくなります。

参考