sinatra-simple-navigationを試す

sinatraのドキュメントを見ていたら拡張ライブラリの一覧があった。
sinatra-simple-navigationというWebアプリのナビゲーションリンクを簡単に実装できるライブラリを試したのでメモ。

インストール

bundlerを使うと他を汚さないのでうれしい。

Gemfile

source 'http://rubygems.org'
gem 'sinatra-simple-navigation'


bundle install

$ bundle install
Fetching source index for http://rubygems.org/
Installing activesupport (3.0.3) 
Installing simple-navigation (3.0.2) 
Installing sinatra-simple-navigation (3.0.2) 
Using bundler (1.0.3) 
Your bundle is complete! It was installed into /Users/**********************


activesupportとsimple-navigationもインストールされた。
sinatra-simple-navigatorはRails用のsimple-navigationをsinatraで使えるようにしてあるだけみたい。


設定

とりあえずREADMEのUsageのとおりrequireとregisterを追加。
sinatraでは拡張ライブラリの組み込みはhelpers/registerを使うのが作法らしい。
helpers/registerの違いについては ここ が参考になった。

app.rb

...

require 'sinatra/simple-navigation'        #追加

class MyApp < Sinatra::Base
  register Sinatra::SimpleNavigation       #追加

  ...


試す

simple-navigationのドキュメントを見ると config/navigation.rbを作れ とある。
まるまるコピーでいいや。

config/navigation.rb

SimpleNavigation::Configuration.run do |navigation|
  navigation.items do |primary|
    primary.item :books, 'Books', '/books' do |books|
      books.item :fiction, 'Fiction', '/books/fiction'
      books.item :history, 'History', '/books/history'
      books.item :sports, 'Sports', '/books/sports'
    end
    primary.item :music, 'Music', '/music' do |music|
      music.item :rock, 'Rock', '/music/rock'
      music.item :pop, 'Pop', '/music/pop'
      music.item :alternative, 'Alternative', '/music/alternative'
    end
    primary.item :dvds, 'Dvds', '/dvds' do |dvds|
      dvds.item :drama, 'Drama', '/dvds/drama'
      dvds.item :action, 'Action', '/dvds/action'
      dvds.item :comedy, 'Comedy', '/dvds/comedy'
    end
  end
end


表示はrender_navigationメソッドを使う。
オプションを指定しなければ通常のナビゲーションリンクが、
rendererにbreadcrumbsを指定するとパンくずリストが出力される。
join_withは階層間のマーク(下記の例だと » )

views/index.haml

%h1 sample
%hr
= render_navigation(:renderer => :breadcrumbs, :join_with => ' &raquo; ')
%hr
= render_navigation


で、こんな感じ。




Booksリンクを押すと・・・




さらにHistoryリンクを押すと・・・




うん、ちゃんと機能している。



Historyリンクを押した後のHTML。選択した要素のclassが selected になっている。

<h1>sample</h1> 
<hr /> 
<div class='' id=''>
  <a href='/books' method=''>Books</a> &raquo; <a href='/books/history' method=''>History</a>
</div> 
<hr /> 
<ul class='' id=''>
  <li class='selected' id='books'>
    <a href='/books' class='selected'>Books</a>
    <ul class='' id=''>
      <li id='fiction'>
        <a href='/books/fiction' >Fiction</a>
      </li>
      <li class='selected' id='history'>
        <a href='/books/history' class='selected'>History</a>
      </li>
      <li id='sports'>
        <a href='/books/sports' >Sports</a>
      </li>
    </ul>
  </li>
  <li id='music'>
    <a href='/music' >Music</a>
  </li>
  <li id='dvds'>
    <a href='/dvds' >Dvds</a>
  </li>
</ul> 


levelオプション (render_navigation)

表示する階層を制限できる。

views/index.haml

%h1 sample
%hr
= render_navigation(:renderer => :breadcrumbs, :join_with => ' &raquo; ')
%hr
= render_navigation(:level => 1)


Booksリンクを押しても下層のリンクが表示されない。




expand_allオプション (render_navigation)

true で全階層を表示できる。

views/index.haml

%h1 sample
%hr
= render_navigation(:renderer => :breadcrumbs, :join_with => ' &raquo; ')
%hr
= render_navigation(:expand_all => true)






もっと深く

アイテムにブロックを渡したら・・・

SimpleNavigation::Configuration.run do |navigation|
  navigation.items do |primary|
    primary.item :books, 'Books', '/books' do |books|
      books.item :fiction, 'Fiction', '/books/fiction'
      books.item :history, 'History', '/books/history'
      books.item :sports, 'Sports', '/books/sports' do |sport|        #変更
        sport.item :football, 'Football', '/books/sports/football'    #追加
        sport.item :baseball, 'Baseball', '/books/sports/baseball'    #追加
      end                                                             #追加
    end
    primary.item :music, 'Music', '/music' do |music|
      music.item :rock, 'Rock', '/music/rock'
      music.item :pop, 'Pop', '/music/pop'
      music.item :alternative, 'Alternative', '/music/alternative'
    end
    primary.item :dvds, 'Dvds', '/dvds' do |dvds|
      dvds.item :drama, 'Drama', '/dvds/drama'
      dvds.item :action, 'Action', '/dvds/action'
      dvds.item :comedy, 'Comedy', '/dvds/comedy'
    end
  end
end


掘れた。




あとは・・・

動的ナビゲーションとかDOMのclass/id指定とかが残っているけど、とりあえずここまで。。。