jekyll

このサイトはjekyllで生成していますが、カテゴリ一覧+記事を作る際に少し苦労したので書いておきます。

最終目標

カテゴリ別にページを表示したい。

カテゴリ1
・カテゴリ1の記事
・カテゴリ1の記事

カテゴリ2
・カテゴリ2の記事
・カテゴリ2の記事

作ってみる

検索してみると、Jekyllの投稿記事に指定したカテゴリを参照するには? というページが見つかりました。
ここでの取得方法を引用させていただくと、

<h4>カテゴリnewsの記事一覧</h4>
<ul>
{% for post in site.categories.news %}
  <li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>
<h4>カテゴリjekyllの記事一覧</h4>
<ul>
{% for post in site.categories.jekyll %}
  <li><a href="{{ post.url }}">{{ post.title }}</a></li>
{% endfor %}
</ul>

ひとつひとつのカテゴリを手動で書き足すことで追加しているようです。
しかしこれではカテゴリを追加した事にこのページも書きなおさなくてはなリません。忘れてしまうこともあるので自動で生成されたほうが便利です。

自動生成を試みる

さきほどのコードを少し改変してみました。

{% for category in  site.categories %}
  <h4>{{ category[0] }}の記事一覧</h4>
  <ul>
  {% for post in site.categories.{{ category[0] }} %}
    <li><a href="{{ post.url }}">{{ post.title }}</a></li>
  {% endfor %}
  </ul>
{% endfor %}

4行目で取り出したカテゴリ名を次のfor文に突っ込んでそのカテゴリの記事を取り出そう作戦です。
しかしこれではカテゴリ名は表示されますが、肝心の記事一覧は取り出すことができませんでした。
(無理やり結合しているのでしっかりと認識されていないのかな。)

試行錯誤の末に

目標達成

いろいろやってみてうまく行ったコードがこれです。

{% for category in site.categories %}
  <h4>{{ category[0] }}</h4>
  <ul>
  {% for posts in category %}
    {% for post in posts %}
      {% if post.title != nil %}
        <li><a href="{{ post.url }}">{{ post.title }}</a></li>
      {% endif %}
    {% endfor %}
  {% endfor %}
  </ul>
{% endfor %}

for文を3段階踏んでいます。
途中のifは、なぜかpostに情報のない記事があり、不要な行が生成された為にはさみました。

また、この方法ではカテゴリ名が完全一致している必要があるので、
大文字小文字を分別しないようにする場合はLiquid referenceを参考に試行錯誤してみてください。

あとはYAML Front Matterを追記すればページの完成ですね。

ソースの見た目

上記のコードではソースを見た時に空行がたくさん出来て気持ちよくないので少し変えます。

{% for category in site.categories %}
<h4>{{ category[0] }}</h4>
<ul>
  {% for posts in category %} {% for post in posts %} {% if post.title != nil %}
  <li><a href="{{ post.url }}">{{ post.title }}</a></li>
  {% endif %} {% endfor %} {% endfor %}
</ul>
{% endfor %}
あとがき

これで手作業から開放される。
ちなみにこのサイトではh4をh3にして、それぞれのカテゴリページにリンクを貼ってます。

{% for category in site.categories %}
<a href="{{ category[0] }}"><h3>{{ category[0] }}</h3></a>
<ul>
  {% for posts in category %} {% for post in posts %} {% if post.title != nil %}
  <li><a href="{{ post.url }}">{{ post.title }}</a></li>
  {% endif %} {% endfor %} {% endfor %}
</ul>
{% endfor %}