Nanocでディレクトリ構造通りのリンクを表示する

Sphinxのtoctreeっぽいことがやりたかったのでヘルパーを作った。
しかし挙動の違うものになったので名前変えた方がいいかもしれない。ところでtoctreeってどういう意味なんだろう。

とにかく「ディレクトリ構造 = 文書構造」ということができるようになった。

<%= toctree %>

と書くと現在のディレクトリを基準にツリー状のリンクリストが表示される。

module Nanoc3
module Helpers
module TocTree
def toctree(*args)
ids = args.select{|arg| arg.is_a?(String) }
ids = ['*'] if ids.empty?
opts = args.reject{|arg| arg.is_a?(String) }.first || {}
opts[:from] ||= @item.identifier
items = titled_items
.select{|item| item.identifier =~ /^#{ids.join('|')}/ }
.select{|item| !item.parent.nil? && item.parent.identifier == opts[:from] }
.sort{|i1, i2| i1.identifier <=> i2.identifier }
to_list(items, opts)
end
private
def titled_items
@items.reject{|item| item[:title].nil? }
end
def to_list(items, opts, depth = 0)
return "" if !opts[:maxdepth].nil? && opts[:maxdepth] <= depth
html = '<ul>'
items.each do |item|
next if opts[:except] && opts[:except].include?(item.identifier)
html += "<li>#{link_to(item[:title], item)}</li>"
# html += "<li>#{link_to(item.identifier, item)}</li>"
if not item.children.empty?
html += to_list(item.children, opts, depth + 1)
end
end
html += '</ul>'
end
end
end
end

Nanocのテストハーネスを作るのがしんどかったので、テスト書いてないけど今考えるとモックとか使えばよかったのかも。

ディレクトリ構造
  • /
    • dir_a
      • index.md
      • x.md
      • y.md
      • z.md
    • dir_b
      • index.md
    • dir_c
      • index.md

実装の都合上各ディレクトリにindex.mdが必要。

ルートから表示
<%= toctree :maxdepth => 1, :from => '/' %>

fromオプションでidentifierを指定すると現在の位置に関係なく、その子要素からのリストを表示する。
maxdepthを指定すると表示する階層を制御できる。

レイアウトファイルなどでメニューを表示したいときなどに。

指定したディレクトリのみを含む
<%= toctree '/dir_a/', '/dir_b/' %>

ディレクトリを複数指定できる。

含まないディレクトリやアイテムを指定する
<%= toctree '/dir_a/', :except => ['/dir_a/y/', '/dir_a/x/'] %>

:exceptオプションに配列でidentifier指定する。

Nanocでディレクトリ構造通りのリンクを表示する” に対して2件のコメントがあります。

  1. さく より:

    tocといえばtable of contentsとゆーことで。

  2. akahige より:

    なるほど!

コメントは受け付けていません。

次の記事

Vimテクニックバイブル