Octopressでカテゴリーの一覧みたいのを実装する

Octopressはそれなりに高機能なのにも関わらず、なぜかカテゴリーの一覧を表示する機能がありませんでした。

仕方ないので、自分で実装することにしました。

今回の記事は、次の画像のようなカテゴリーの一覧をサイドバーに表示するまでのメモです。

カテゴリーの一覧

前提知識として、Octopressのサイドバーをカスタマイズするためには、次の2つの作業が必要です。 ここでは、categoriesという名前のサイドバーを追加します。

  1. source/_includes/asides/categories.htmlというファイルを作る。
  2. _config.ymldefault_asides:asides/categories.htmlを加える。ex.

あとは、1,のsource/_includes/asides/categories.htmlにカテゴリーの一覧を表示する機能をうまく実装しなくてはなりません。

siteというグローバル変数のダンプを手がかりに、site.categoriesというハッシュが存在することがわかりました。

JekyllのLiquidテンプレートエンジンの文法がよくわからないので、以下のサイトなどを参考にして学習しました。

しかし、site.categoriesはカテゴリー名をキーとして値が記事の本文のHTMLへの参照(?)の配列としたハッシュになっており、 そのままではURLが取得できず、カテゴリー名からURLに変換する処理をLiquidの文法だけで実装するのは無理だと気が付きました。

で、どうしたかというと、Liquidを拡張しました。Jekyll::Filtersにメソッドを定義すると、Liquidからそのメソッドを呼び出せるようになります。

最終的に、_config.ymlを編集後、 source/_includes/asides/categories.htmlplugins/category_generator.rbを次のようにしたら、うまくいきました。

source/_includes/asides/categories.html

source/_includes/asides/categories.html はこれだけです。

{.{.は消してください。

<section class="well">
  <ul id="categorys" class="nav nav-list">
    <li class="nav-header">Categorys</li>
    {.{ site.categories | site_categories_links }}
  </ul>
</section>

plugins/category_generator.rb

plugins/category_generator.rbJekyll::Filterssite_categories_linksというメソッドを追加します。

module Jekyll
  module Filters
    # Outputs a list of categories as comma-separated <a> links. This is used
    # to output the category list for site's all categories.
    #   
    # Returns string
    #   
    def site_categories_links(categories)
      def adjust_fontsize(size)
        [20, size*2 + 8].min
      end
      dir = @context.registers[:site].config['category_dir']
      categories = categories.to_a.sort.map do |key, val|
        "<a class='category' style='font-size:#{adjust_fontsize(val.size)}px;' href='/#{dir}/#{key.gsub(/_|\P{Word}/, '-').gsub(/-{2,}/, '-').downcase}/'>#{key}(#{val.size})</a>"
      end
      categories.join(' / ')
    end
  end

end

とりあえず、これでカテゴリーの一覧を表示することができました。

comments powered by Disqus

gam0022.net's Tag Cloud