kaminari のページネーションリンクをカスタマイズする
Rails でページネーションを行うための定番 gem、 kaminari。
ページネーションリンクを view に表示するためのヘルパ(paginate
)も用意されていてたいへん便利です。
このヘルパを使ってデフォルトで出力されるリンクはとても簡素なものですが、テンプレートをカスタマイズすることで好みのスタイルに変更することができます。
今回は、Twitter Bootstrap4 1に用意されている Pagination コンポーネント のスタイルを適用してみたので、手順をメモしておきます。
スタイルのプレビュー
デフォルト
カスタマイズ後
最初のページへ戻るリンクの表示/非表示や、何ページ先まで省略せずリンクを出すかなどの細かい設定は、ヘルパのオプションで変更できます。2
環境
- Ruby 2.3.0
- Rails 4.2.3
- kaminari 0.16.3
- Bootstrap 4.0.0.alpha3
- haml 4.0.7
gem のインストール/セットアップ
Rails のプロジェクトは作成済みとします。
Twitter Bootstrap 4
Bootstrap 4 には公式の gem が用意されています。
以下のページに従って Bootstrap をインストール/設定してください。
https://github.com/twbs/bootstrap-rubygem
kaminari
kaminari のインストールは以下の公式ドキュメントを参照。
Gemfile に追記して bundle install
するだけです。
ページネーションリンクのカスタムテンプレートを出力
以下のコマンドで、ページネーションリンクの view テンプレートが app/views/kaminari
以下に展開されます。
% rails g kaminari:views default -e haml
# erb な人はこちら:
% rails g kaminari:views default
% tree app/views/kaminari
app/views/kaminari/
├── _first_page.html.haml # 最初のページに戻るリンク
├── _gap.html.haml # 省略されたページを示す表示(...)
├── _last_page.html.haml # 最後のページヘのリンク
├── _next_page.html.haml # 次のページへのリンク
├── _page.html.haml # 1, 2, 3 など、各ページに飛ぶためのリンク
├── _paginator.html.haml # 同じ他のテンプレートを呼び出すための親テンプレート
└── _prev_page.html.haml # 前のページへのリンク
テンプレートは細かい部品に分かれています。
これらを上書きして Bootstrap の Pagination コンポーネントが要求するマークアップに変更しましょう。
テンプレートの上書き
以下のように上書きします。
%li.page-item.prev{ class: "#{'disabled' if current_page.first?}" }
= link_to (current_page.first? ? "#" : url), class: "page-link", "aria-label" => "First", :remote => remote do
%span{"aria-hidden" => "true"} «
%span.sr-only
= t('views.pagination.first').html_safe
%li.page-item.gap
.page-link
= t('views.pagination.truncate').html_safe
%li.page-item.next{ class: "#{'disabled' if current_page.last?}" }
= link_to (current_page.last? ? "#" : url), class: "page-link", "aria-label" => "Last", :remote => remote do
%span{"aria-hidden" => "true"} »
%span.sr-only
= t('views.pagination.last').html_safe
%li.page-item.next{ class: "#{'disabled' if current_page.last?}" }
= link_to (current_page.last? ? "#" : url), class: "page-link", "aria-label" => "Next", :remote => remote do
%span{"aria-hidden" => "true"} ›
%span.sr-only
= t('views.pagination.next').html_safe
%li.page-item{ class: "#{'active' if page.current?}" }
= link_to url, class: "page-link", remote: remote do
= page
- if page.current?
%span.sr-only (current)
= paginator.render do
%nav.text-xs-center
%ul.pagination.pagination-sm
= first_page_tag
= prev_page_tag
- each_page do |page|
- if page.left_outer? || page.right_outer? || page.inside_window?
= page_tag page
- elsif !page.was_truncated?
= gap_tag
= next_page_tag
= last_page_tag
%li.page-item.prev{ class: "#{'disabled' if current_page.first?}" }
= link_to (current_page.first? ? "#" : url), class: "page-link", "aria-label" => "Previous", :remote => remote do
%span{"aria-hidden" => "true"} ‹
%span.sr-only
= t('views.pagination.previous').html_safe
ページネーションリンクの出力
モデルの配列に相当するオブジェクトを引数に、ビューで paginate
ヘルパを呼び出せば OK。
= paginate @users
当該ページをブラウザで開くと、前掲のスタイルでページネーションリンクが出ているはずです。
参考文献
-
今回は Bootstrap 4 を用いていますが、Bootstrap 3 でも同じマークアップで動くと思います。 ↩
-
具体例は公式ドキュメントにまとまっています: https://github.com/amatsuda/kaminari#helpers ↩