Hugo を使った個人サイトの作り方 7 固定ページの作成(2) Shortcode

Hugo アイキャッチ画像

前回はSection(※./content/以下のディレクトリのこと)直下の_index.mdを固定ページとして出力するようList Templateに条件分岐を加えました。今回からいよいよ、固定ページのコンテンツ作成に入っていきます。主にshortcodeとDataディレクトリからの参照を紹介します。

二次創作小説の目録ページの基本的なソースコードは以下のようになっています。

二次創作小説目録ページのソースコード[hugo-nijisource.jpg(158434byte)]

このmarkdownファイルはhugo serverコマンド等でHTML出力されると以下のようになります。

二次創作小説目録ページの実際の表示[hugo-fictoc.jpg(154816byte)]

赤枠で囲われているのがHugoの自動テンプレート機能で出力している部分です。

パンくずリスト

上部から説明すると、パンくずリストはパンくずリストを表示する - まくまくHugoノート の部分テンプレート記述をそのまま持ってきております。ページ下部にも装飾を変えて登場しますがコードは同じです。

ページ内目次

ページ内の目次については特別なことは何もせず、hugoの標準機能を使っただけです。Table of Contents | Hugo ちなみにこの機能を使う場合、hugo.tomlで細かく設定できます。

[markup]
  [markup.tableOfContents]
    endLevel = 3
    ordered = false
    startLevel = 2

これがデフォルト設定です。HTMLの見出し「h」要素のレベルで開始、終了を制御しています。この例では<h2>から始まり<h3>で終わります。orderedは目次のリストが<ol>(番号リスト)になるか<ul>(箇条書きリスト)になるかというフラグですね。

HugoのShortcode

しかし、目次をいろいろな箇所に柔軟に入れたい場合があると思います。 私はHugoのShortcode機能(Shortcodes | Hugo)を使い、markdownファイルからも参照できるようにしました。

Shortcodeとは、複数のコードを短い記述で呼び出せる機能です。Wordpressにも同じような機能があるらしい…?

といってもこれも簡単です。./layouts/shortcodes/[shortcodename].htmlとして保存したものをHTMLタグのように呼び出すだけです。

./themes/Museum/layouts/shortcodes/toc.html

{{ .Page.TableOfContents }}

これだけ書いたtoc.html./layouts/shortcodes/*に置けば、markdownファイルから以下のようにスニペットとして呼び出せます。

{{< toc >}}

これで目次がどこでも出力されるようになります。あとはCSSで装飾を行います。 ショートコードはHugoの内部でもFigure要素、コードハイライト、ツイッター引用、Youtube引用などいろいろ用意されています。自分で使いやすいよう改造したり作ったりできます。

小説目次機能

さて、小説目次機能を作ろうと思います。

今まで使っていたHTMLをmarkdownファイルにベタ書きでもいいのですが、多いと面倒かと思ってshortcodeでData Templateを参照することにしました。

markdownファイル側で設定したタグやカテゴリ、概要を列挙するのでもいいんですが、それだと連作とかをうまく表示できないのです(連作なのに日付が飛んだりしてる)

※pixiv小説のように表示するテーマopera7133/vnovel: Pixiv-like theme for novelsもあるようなので、それを利用するのも手かもしれません。

まず、Data Templateとは、サイトの作業ディレクトリにおける./data/*以下のファイルです。

これらの形式で書かれたデータを変数site.Data.filenameでサイト全体から読み込めます。作品の概要などをこのデータファイルにまとめてしまい、後はHugo側で出力しようと思います。

一作分の表示はYAML記法で次のようになります! ハイフンの後半角スペースで配列を表現します。

※スクショでは二次創作を表示していますが例はオリジナル小説にさせてください。

/data/original.yml

 1- Name : 'ムッシュ・ド・パリは迷わない'
 2  Id: 'monsiourdeparis'
 3  Description: '剣道青年だった大学生・坂本晴樹は朝の自主練の後、奇妙な少女に不運を告げられた。果たしてその日、晴樹は彼女を守ろうとしたばかりに通り魔事件に巻き込まれ、殺人犯となってしまう。自衛隊に収容された彼に告げられたのは、「人が悪霊に憑かれて変化したばけもの」に死刑宣告を与え、それを狩りつづけるという厳しい使命だった。たった一人の少女のために、名を捨て、故郷を捨て、妖刀までもたずさえて、現代の鬼退治がはじまる。'
 4  Addition: '現代伝奇妖怪バトル小説。ダークな感じです。 ** 人が死ぬ結末が多いです ** '
 5  Image: '../img/fic/monsieur.jpg'
 6  Info: 
 7  - Term: 'グッバイ私の初恋(1)'
 8    Url: './novel/mdp01/'
 9    Key: '現代伝奇妖怪バトルもの。ダークな感じ。主人公覚醒ととある事件 2013/07/21'
10  - Term: 'グッバイ私の初恋(2)'
11    Url: './novel/mdp02/'
12    Key: '現代伝奇妖怪バトルもの。ダークな感じ。銃使いの悪さと鬼とのバトル'

以前の目次をそのまま配列にして打ち込んでるだけです…… これを以下のShortcodeで表示します。

/layouts/shortcodes/mokuji.html

 1{{- range (index .Site.Data (.Get 0)) }}
 2{{- $a := index .Info 0 }}
 3  <h4 id="{{- .Id -}}">{{ .Name }}</h4>
 4  {{- if .Image }}
 5  <figure>
 6  <a href="{{- $a.Url -}}" title="この小説を最初から読む"><img src="{{- .Image -}}" alt="{{ .Name }}(タイトル画像)" width="200" height="260" /></a>
 7  </figure>
 8  {{- end -}}
 9  {{- if .Description }}<a href="{{- $a.Url -}}" title="この小説を最初から読む"><div class="description"><p>{{ .Description }}</p></div></a>{{ end }}
10  {{ if .Addition }}<p>{{ .Addition | markdownify }}</p>{{- end }}
11  <dl>
12  {{- range $val := .Info }}
13    <dt><a href="{{- $val.Url -}}">{{ $val.Term }}</a></dt>
14    <dd>{{ $val.Key | markdownify }}</dd>
15  {{- end -}}
16  </dl>
17{{- end -}}

markdownファイルからはショートコード名の後にdataファイル名を引数に指定して{{% mokuji original %}} と書けば後はダラダラと目録が表示されます。二次創作の元ネタ作品名だとか、現パロとか連作とかでいくつかyamlファイルを分けて作って全部このショートコードに流し込んでいきます。

区切り文字が「%」の場合は内容がコンテンツレンダラに渡されます。要するにmarkdownで書いたらそのとおり解釈されるってことです。この場合、Additionキーの中身にmarkdownの強調記法が使われているので、いつも通り{{< mokuji >}}と書いたらベタ書きで出てきますが、「%」を使うと <strong> 要素で囲まれて出力される、っていう違いです。

出力例は画像で示します。

original.ymlの出力例[Hugo-databuild.jpg(43630byte)]

HTMLを直に書いたほうが楽そうではありますがData Templateを知るという意味でこんな感じの実装になっています。次回はいよいよブログでいう記事ページとなる小説本文を作ります。扱う内容としてはbaseofテンプレートとsingleテンプレート、次にカテゴリ、タグ、シリーズ機能などです。