will_paginate で表示をカスタマイズする
趣旨
Rails 2.0 になって、ページ送りの機能が Rails 本体から消えてしまった。will_paginate という gem か、 paginating_find というプラグインを使うのがいまは普通であるらしい。私は will_paginate で、ちょっとページ送り部分の表示をカスタマイズして使ってみた。
情報ソース
will_paginateに移行
will_paginate を使う上で必要な知識がまとまっている。ただし、いまは gem になっているのに注意。
インストール
% sudo gem install will_paginate
として gem をインストールする。そして、 config/environment.rb で
require 'will_paginate'
として読み込めば、準備 OK。
後はコントローラで、
@posts = Post.paginate_by_board_id @board.id, :page => params[:page], :order => 'updated_at DESC'
とすればよい。通常 find_* と各部分を paginate_* と置き換えるだけである。ページ送りのコントロールを表示するには、ビューで、
<%= will_paginate @posts %>
とする。すこぶる簡単。
ページ送りのコントロールのカスタマイズ
ただし、普通はページ送りのコントロールをそのまま使うことはなく、その表示をカスタマイズしたいものだろう。will_paginate gem ディレクトリ以下の lib/will_paginate/view_helpers.rb に、ビューで使用する will_paginate ヘルパーメソッドの定義がある。基本的には、リンクの HTML を生成するカスタマイズされた LinkRenderer クラスを will_paginate ヘルパーメソッドのオプションで指定すればよい。
たとえば、ページ送り部分に次のような HTML を生成したいとする。(正確には、結果は多少異なることになるが、本質的な違いではない)
<ul> <li><a class="prev"><img src="/images/prev.gif" alt="前へ" /></a></li> <li><a href="..." class="">1</a></li> <li><a href="..." class="">2</a></li> <li><a class="gap"><img src="/images/gap.gif" /></a></li> <li><a href="...">6</a></li> <li><a href="...">7</a></li> <li><a href="...">8</a></li> <li><a href="...">9</a></li> <li><a href="..." class="current">10</a></li> <li><a href="...">11</a></li> <li><a href="...">12</a></li> <li><a href="..." class="next"><img src="/images/web/next.gif" /></a></li> </ul>
そのためには、たとえば、config/environment.rb に次のような記述をおく。デフォルトの LinkRenderer である WillPaginate::LinkRenderer を継承してカスタマイズされた CustomLinkRenderer を定義する。
class CustomLinkRenderer < WillPaginate::LinkRenderer def to_html links = @options[:page_links] ? windowed_links : [] # previous/next buttons links.unshift page_link_or_span(@collection.previous_page, %w(disabled prev), %(<img src="/images/prev.gif" alt="前へ">)) links.push page_link_or_span(@collection.next_page, %w(disabled next), %(<img src="/images/next.gif" alt="次へ">)) html = links.join(@options[:separator]) @options[:container] ? @template.content_tag(:ul, html, html_attributes) : html end def gap_marker '<li><a class="gap"><img src="/images/gap.gif" /></a></li>' end def page_link_or_span(page, span_class, text = nil) text ||= page.to_s classnames = Array[*span_class] if page and page != current_page "<li>" + @template.link_to(text, url_for(page), :rel => rel_value(page), :class => classnames[1]) + "</li>" else "<li><a class='#{classnames.join(' ')}'>#{text}</a></li>" end end end
そして、ビューで次のように記述する。
<%= will_paginate @posts, :renderer => 'CustomLinkRenderer' %>
この例自体に深い意味はない。要するに、こういうやり方で簡単に表示がカスタマイズできるということを示してみたかっただけである。詳しくは、lib/will_paginate/view_helpers.rb を参照のこと。