HugoでJSONを出力

2017-11-07

#Hugo

サイトの記事データをJSONで出力したい。手作業は大変。CMSを設置するのも億劫。 ということで、Hugoで出力するようにしました。

サンプルコード

前提

やりたいこと

MarkDownで書いた記事データをJSONで出力する。

Hugoにした理由

他の静的サイトジェネレータをいくつか試したのですが、次のような印象でした。

Middleman
うまくテンプレートでJSON出力できなかった。
Jekyll
ページ一覧をJSON出力する際、list.jsonという出力ファイル名を作れなかった。
Hexo
こちらも、ページ一覧をJSON出力する際、list.jsonというファイル名を作れなかった。

メモを破棄したため正直なところ空覚えなのと、あまり深く確認せず試していたので、間違っているかもしれません。 予めご容赦ください。

手順

手順は次のとおりです。

  1. config.tomlでJSONを出力するように設定。
  2. 出力したい内容となるようにJSON出力用テンプレートを調整。
  3. hugoで出力。

1. config.tomlでJSONを出力するように設定

記事データをすべてJSON出力したいので、sectionページタイプの出力フォーマットにJSONを追加します。

config.toml

baseURL = "http://example.org/"
languageCode = "en-us"
title = "My New Hugo Site"

[outputs]
section = ["JSON", "HTML"]

2. 出力したい内容となるようにJSON出力用テンプレートを調整

JSON出力用テンプレートを作成します。 postsディレクトリ下に記事データを入れるようにしたので、テンプレートはposts/list.jsonとして作成します。

posts/list.json

{% raw %}
{
  "posts": [
    {{ $list := .Data.Pages -}}
    {{ $len := (len $list) -}}
    {{ if lt 0 $len -}}
      {{ range first 1 $list -}}
      {
        "id" : {{ .Date.Format "20060102150405" | jsonify }},
        "date" : {{ if .Date }}{{ .Date.Format "2006.01.02" | jsonify }}{{else}}""{{end}},
        "title" : {{ .Title | jsonify }},
        "summary" : {{ .Summary | jsonify }},
        "body" : {{ .Content | jsonify }},
        "tags" : {{ if .Params.tags }}{{ .Params.tags | jsonify }}{{ else }}[]{{ end }},
        "some-ex-param" : {{ if .Params.someexparam }}{{ .Params.someexparam | jsonify }}{{ else }}false{{ end }}
      }
      {{- end -}}
    {{- end -}}
    {{- if lt 1 $len -}}
      {{- range after 1 $list -}}
      ,{
        "id" : {{ .Date.Format "20060102150405" | jsonify }},
        "date" : {{ if .Date }}{{ .Date.Format "2006.01.02" | jsonify }}{{else}}""{{end}},
        "title" : {{ .Title | jsonify }},
        "summary" : {{ .Summary | jsonify }},
        "body" : {{ .Content | jsonify }},
        "tags" : {{ if .Params.tags }}{{ .Params.tags | jsonify }}{{ else }}[]{{ end }},
        "some-ex-param" : {{ if .Params.sameexparam }}{{ .Params.sameexparam | jsonify }}{{ else }}false{{ end }}
      }
      {{- end -}}
    {{- end }}
  ]
}
{% endraw %}

3. hugoで出力

# 実行
$ hugo

次のようなファイルができていれば完成です。

index.json

{
  "posts": [
    {
      "id": "20171004010101",
      "date": "2017.10.04",
      "title" : "Post4",
      "summary": "etc4 etc4\u0026hellip;",
      "body": "\u003cp\u003eetc4 etc4\u0026hellip;\u003c/p\u003e\n",
      "tags": [],
      "some-ex-param": "test4"
    }, {
      "id": "20171003010101",
      "date": "2017.10.03",
      "title": "Post3",
      "summary" : "etc3 etc3\u0026hellip;",
      "body": "\u003cp\u003eetc3 etc3\u0026hellip;\u003c/p\u003e\n",
      "tags": [],
      "some-ex-param": false
    }, {
      "id": "20171002010101",
      "date": "2017.10.02",
      "title": "Post2",
      "summary" : "etc2 etc2\u0026hellip;",
      "body": "\u003cp\u003eetc2 etc2\u0026hellip;\u003c/p\u003e\n",
      "tags": [],
      "some-ex-param": false
    }, {
      "id": "20171001010101",
      "date": "2017.10.01",
      "title": "Post1",
      "summary" : "etc1 etc1\u0026hellip;",
      "body": "\u003cp\u003eetc1 etc1\u0026hellip;\u003c/p\u003e\n",
      "tags": [],
      "some-ex-param": false
    }
  ]
}

補足

Hugoは、”list”というテンプレート名を持つものを一覧ページのテンプレートと認識します。 一覧ページのテンプレートについて

最初、この仕様の理解ができておらず、手間取りました。 とほほ……

静的サイトジェネレータはWebサイトの作成を目的としなくても、こういったシードデータの作成にも使えて便利ですね。

© kdtakahiro 2018