Nanoc で年月毎の記事のアーカイブを表示できるようにする。
Table of Contents
Open Table of Contents
年月毎のページ(Item
)を取得し表示する
まずは、年月毎のページ(Item
)を取得するためのヘルパーを用意する。
lib/helper.rb
に以下のヘルパーを追加する。
lib/helper.rb
:
def articles_by_year_month
result = {}
current_year = current_month = hash_of_year = items_of_the_month = nil
sorted_articles.each do |article|
d = Date.parse(article[:created_at])
if current_year != d.year
current_month = nil
current_year = d.year
hash_of_year = result[current_year] = {}
end
if current_month != d.month
current_month = d.month
items_of_the_month = hash_of_year[current_month] = []
end
items_of_the_month << article
end
result
end
def mm_str_month(month)
sprintf("%02d", month)
end
articles_by_year_month
により、{ 年 => { 月 => [Item の配列] } }
というデータ構造の Hash が取得できるようになる。
より具体的には、{ 2010 => { 5 => [item1, item2], 6 => [item3, item4] } }
となる。
上記で取得されるデータから、全ての記事の中から年月毎の記事の一覧を表示する部分を追加していく。
部分テンプレートとして、layouts/_articles_by_year_month.html
ファイルを作成し、以下のコードを記述する。
layouts/_articles_by_year_month.html
:
<% articles_by_y_m = articles_by_year_month %>
<ul>
<% articles_by_y_m.keys.sort_by{|e| -e}.each do |year| %>
<% articles_by_y_m[year].keys.sort_by{|e| -e}.each do |month| %>
<li>
<%= link_to("#{year}/#{mm_str_month(month)}", "/archives/#{year}/#{mm_str_month(month)}/") %>
(<%= articles_by_y_m[year][month].size %>)
</li>
<% end %>
<% end %>
</ul>
上記の部分テンプレートを表示するために、layouts/default.html
に記載されているサイドバー部分に表示部分を追加しておく。
<div id="sidebar-wrapper">
<h2>Archives</h2>
<%= render('_articles_by_year_month') %>
...
これで、記事の年月とその件数、年月毎の記事一覧を表示するためのリンク先(e.g. /archives/2010/06/
)までは表示できるようになった。このサイトでいうと、以下の部分。
次に、記事一覧を表示するためのページを用意する。
年月毎の記事一覧を表示するためのページ(Item
)を動的に生成する
同じタグを持つページの一覧を表示する際に実施した方法(Nanoc のカスタマイズ - タグを管理する)で年月毎の記事一覧も用意することにする。
Rules
の preprocess
で Item
を動的に生成することにする。
ロジック自体は、helper に切り出しておく。
lib/helper.rb
:
def create_year_month_archive_pages
articles_by_year_month.each do |year, month_hash|
month_hash.each do |month, articles|
month_str = sprintf("%02d", month)
items << ::Nanoc3::Item.new(
"<%= render('_archive_by_year_month', :year => #{year}, :month => #{month}) %>",
{ :title => "Archives: #{year}/#{month_str}", :is_hidden => true },
"/archives/#{year}/#{month_str}/",
:binary => false
)
end
end
end
上記の Item
インスタンス生成の際に使用している部分テンプレート _archive_by_year_month
は、以下の内容となる。
layouts/_articles_by_year_month.html
:
<h2>Archive: <%= year %>/<%= mm_str_month(month) %></h2>
<ul>
<% articles_by_year_month[year][month].each do |article| %>
<li>
<%= link_to(article[:title], article.path) %><br />
<span class="meta">
<%= render('_summary_meta_info', :item => article) %>
</span>
</li>
<% end %>
</ul>
Rules
の preprocess
メソッドのブロックに以下の記載を追加し、年月毎のページの一覧を表示するための Item を動的に生成する。
preprocess do
...
create_year_month_archive_pages
end
以上で完了となる! このサイトでいうと、以下の部分。
参考サイト
関連記事
- 静的な Web サイト生成ツール Nanoc 基本編 - まずは試してみる
- Nanoc のカスタマイズ - 最近の記事一覧の表示
- Nanoc のカスタマイズ - タグを管理する
- Nanoc のカスタマイズ - 年月毎の記事のアーカイブを用意する