やりたいこと

記事にシェア数を表示したい。

当ブログのシェア数表示
当ブログのシェア数表示

なぜ ?

Hugo は静的サイトジェネレーターです。
この「静的サイト」であることが大きなメリットであり、逆に言うと制限が大きくデメリットでもあります。

具体的には、Hugo で生成したサイトには通常「検索やお問い合わせフォーム」を設置できません。

同じように、「記事ごとのシェア数というデータ」は可変なもののため、取扱が難しいのです。

実装方針

JavaScript は使用しない

静的サイトに動的機能を実装する手段として、まず思い浮かぶのは JavaScript で頑張る方法です。

しかしながら「ブログ記事閲覧のたびにシェア数を取得する」ような実装ですと、「静的だから軽い」というメリットを潰してしまい、本末転倒です。

data から情報をロードする

調べてみると、Hugo では「data ディレクトリ以下のファイルにアクセスできる」ことがわかりました。

ファイルからのデータロードはビルド時に行われ、動的っぽいことをしてもビルド後、純粋な HTML ファイルを生成する点は変わりません。
つまり閲覧時の速度影響がないのです。

この機能を利用してシェア数表示機能を実装します。


対応フォーマットは次の 3 種類です。

  • JSON
  • yaml
  • toml

詳しくは公式をご覧ください。

Hugo
Templates > Data Templates
https://gohugo.io/templates/data-templates/

実装

「シェア数表示」の実装は次のようにします。

  • 1. シェア数データ用の JSON ファイルを生成する
  • 2. 1 ファイルを data ディレクトリ以下に保存する
  • 3. テンプレートで JSON ファイルを読み込んで出力する

上記 1, 2 は PHP 実装です。

JSON ファイルについて

シェア数を問い合わせ、JSON ファイル生成する処理は PHP でスクリプトを組み定期実行しています。

このスクリプトの処理フローについて簡単に解説いたします。

記事を調べる

Hugo は 1 記事を 1 ファイルで管理します。

はじめに「どんな記事があるか」を調べます。
これは post ディレクトリ以下の記事ファイルをリストアップする処理です。

シェア数を取得する

当ブログは記事ファイル名をそのまま URL としています。

リストアップした記事ファイルから 記事 URL を求め、URL 単位で各サービスにシェア数を問い合わせます。

ファイル出力する

問い合わせたシェア数を JSON に加工しファイル出力します。

JSON のフォーマットは次のようにしました。

1{"total":0,"tweet":0,"hatena":0}

JSON のファイル名は記事のファイルと同一とし、ファイル名で関連づくようにしました。
hoge_fuga.md というブログ記事なら hoge_fuga.json です。

また、ファイル出力は /data/share/ 以下としました。

JSON ファイル出力ディレクトリ図
JSON ファイル出力ディレクトリ図

JSON ファイルの読み込みと出力

Hugo のテンプレートに次を追加します。

1{{ $json := getJSON "/data/share/" .File.BaseFileName ".json" }}
2{{ if $json.total }}
3<li><i class="fa fa-heart"></i>{{ $json.total }}</li>
4{{ end }}

すると次画像のシェア数が表示されます。

当ブログのシェア数表示
当ブログのシェア数表示

.File.BaseFileName で記事ファイル名を取得し、getJson で JSON ファイルをロード。 $json.total で JSON ファイルのデータにアクセスしています。

こうしてみるとシンプルであることがわかると思います。

この実装の弱点

この実装には不備があります。

記事追加時に JOSN ファイルも用意しておかないとファイルにアクセスできず、エラーとなってしまうのです。

1ERROR 2018/07/02 17:18:00 in .Render: Failed to execute template "detail.html": template: detail.html:17:18: executing "detail.html" at <getJSON "/data/share...>: error calling getJSON: unexpected end of JSON input

「本番にアップされて障害につながる」ことはありえませんから、そのままにしてます。

おわりに

Hugo のカスタマイズ例をご紹介いたしました。

先日 Google よりスピードアップデートが発表されました。
このご時世ますます「 高速であることの価値 」が重要視される傾向にあります。
「インフラも整ってこんなに早くなったのに」です。

Hugo はカスタマイズが難しくとっつきにくい面はありますが、この速度はとても貴重ですよ。

この記事の著者 Webrow (うぇぶろう)
Web アプリ開発、 Web 顧問 エンジニア、WordPress サポートいたします。