kaminari のページネーションリンクに Twitter Bootstrap 4 のスタイルを適用する


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 コンポーネントが要求するマークアップに変更しましょう。

テンプレートの上書き

以下のように上書きします。

_first_page.html.haml
%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
_gap.html.haml
%li.page-item.gap
  .page-link
    = t('views.pagination.truncate').html_safe
_last_page.html.haml
%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
_next_page.html.haml
%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
_page.html.haml
%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.html.haml
= 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
_prev_page.html.haml
%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

当該ページをブラウザで開くと、前掲のスタイルでページネーションリンクが出ているはずです。

参考文献


  1. 今回は Bootstrap 4 を用いていますが、Bootstrap 3 でも同じマークアップで動くと思います。 

  2. 具体例は公式ドキュメントにまとまっています: https://github.com/amatsuda/kaminari#helpers