feed

2014年04月17日, 編集履歴

Jekyllでタグをソートして一覧する

 Jekyllを用いたブログで、ブログ記事に付けたタグをソートして一覧することを考える。サイト内の全タグを一覧する場合と、とあるひとつの記事に付けられたタグを一覧する場合のふたつを考える。

サイト内の全タグをソートして一覧する

 タグクラウド的にサイト内の全タグを一覧する場合を考える。Alphabetizing Jekyll Page Tags In Pure Liquid (Without Plugins) – Michael Lanyon’s Blogを参考にした。

 Jekyll処理対象ファイル内で使えるグローバル変数sitesite.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 %}

 上記の例では、tagNamesStringsite.tagsハッシュのキィ(タグ名)が,区切りのひとつの文字列として入る。ここで、上記の例を見た目上解りやすく改行、インデント等すると、それらも含めてtagNamesStringに入ってしまうので、余計な改行、空白は入れないように注意する。

 次にtagNamesStringsplitフィルタで配列に変換、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.tagssortフィルタに掛けてアルファベット順にソートし、{% assign %}で新しい変数に割り当てる。上記の例ではsortedTagNamesにソートされたタグ文字列の配列が入る。
 あとはsortedTagNames{% for %}文に掛けてタグ一覧を出力するだけ。ここでも前項と同様単なるリスト要素として出力している。ハイパーリンクとして出力する際には別途タグ毎のページを作るなりして、そこへリンクを張る。当ブログでは簡易的な検索機能を実装し、そこでタグを付けられた記事を列挙するようにしている。