2014年04月17日, 編集履歴
Jekyllでタグをソートして一覧する
Jekyllを用いたブログで、ブログ記事に付けたタグをソートして一覧することを考える。サイト内の全タグを一覧する場合と、とあるひとつの記事に付けられたタグを一覧する場合のふたつを考える。
サイト内の全タグをソートして一覧する
タグクラウド的にサイト内の全タグを一覧する場合を考える。Alphabetizing Jekyll Page Tags In Pure Liquid (Without Plugins) – Michael Lanyon’s Blogを参考にした。
Jekyll処理対象ファイル内で使えるグローバル変数site
のsite.tags
に、サイト内の全タグ情報がハッシュとして入っている。タグ名がキィ、そのタグが付けられた記事のハッシュが配列として値になっている。たとえば{{ site.tags['jekyll'][0].title }}
とすれば、jekyll
というタグが付けられた日付順で一件目の記事のタイトルが出力される。
ハッシュそのままではキィをソートできない。配列であれば{{ array | sort }}
のようにsort
フィルタでソートすることが可能。そこで、site.tags
ハッシュからキィを取り出し、それを配列に入れてソートすることを考える。ここでは{% capture %}
と{% for %}
を使う方法を紹介する。
Jekyll(Liquid)の{% capture %}
タグを使うと、その中で出力される文字列を変数に詰め込むことができる。
{% capture myString %}hoge foo bar{% endcapture %}
のようにすれば、myString
にはhoge foo bar
という文字列が入る(実際の出力にはhoge foo bar
は反映されない)。
一方、{% for %}
文の機能について、{% for %}
文をハッシュに対して使うと、以下のように各キィ・値ペアが配列になってitem
変数に入る(配列のインデックス0
がキィ、1
が値)。
{% for item in hash %}
key: {{ item[0] }}, value: {{ item[1] }}
{% endfor %}
{% capture %}
の中で{% for %}
文をハッシュに対して用いてキィを取り出し、,
区切りのひとつの文字列を作る。
{% capture tagNamesString %}{% for tag in site.tags %}{{ tag[0] }}{% unless forloop.last %},{% endunless %}{% endfor %}{% endcapture %}
上記の例では、tagNamesString
にsite.tags
ハッシュのキィ(タグ名)が,
区切りのひとつの文字列として入る。ここで、上記の例を見た目上解りやすく改行、インデント等すると、それらも含めてtagNamesString
に入ってしまうので、余計な改行、空白は入れないように注意する。
次にtagNamesString
をsplit
フィルタで配列に変換、sort
フィルタでソートして変数に割り当てる。変数割り当ては{% assign %}
タグを用いる。
{% assign sortedTagNames = tagNamesString | split:',' | sort %}
これでsortedTagNames
はソートされたタグ名の配列になる。あとはsortedTagNames
配列を{% for %}
文に掛けてやれば、サイト内で使われている全タグをソートして一覧できる。
<ul>
{% for tagName in sortedTagNames %}
<li>{{ tagName }}</li>
{% endfor %}
</ul>
配列を{% for %}
文に掛けた場合は、各要素がそのまま一時変数に入る。上記では単にリストとして出力しているが、ハイパーリンクとして出力する際は別途タグ毎のページを作るなりしてそこへリンクを張る。当ブログでは簡易的な検索機能を実装し、そこでタグを付けられた記事を列挙するようにしている。
ひとつのブログ記事に付けられたタグを一覧する
とあるひとつのブログ記事を出力する際に、その記事に付けられているタグを一覧する場合を考える。
記事内で使えるpage
変数のpage.tags
に、その記事に付けられたタグの文字列が配列として入っている。site.tags
ハッシュとは違い、page.tags
は文字列の配列である。したがって、そのままsort
フィルタを用いることができる。
{% assign sortedTagNames = page.tags | sort %}
<ul>
{% for tagName in sortedTagNames %}
<li>{{ tagName }}</li>
{% endfor %}
</ul>
page.tags
にはYAML Front-matterで設定した順にタグ文字列が配列として入っている。page.tags
をsort
フィルタに掛けてアルファベット順にソートし、{% assign %}
で新しい変数に割り当てる。上記の例ではsortedTagNames
にソートされたタグ文字列の配列が入る。
あとはsortedTagNames
を{% for %}
文に掛けてタグ一覧を出力するだけ。ここでも前項と同様単なるリスト要素として出力している。ハイパーリンクとして出力する際には別途タグ毎のページを作るなりして、そこへリンクを張る。当ブログでは簡易的な検索機能を実装し、そこでタグを付けられた記事を列挙するようにしている。