Laravel4、ペギネーションリンクを取り替える

タグ: Laravel4  

これは、Laravel Advent Calendar 2013 の6日目の記事です。

前日に引き続き、Laravelに巣食う悪の権化、悪魔博士改め、川瀬が担当します。

ペギネーションの表示形式は、手を加えなくても切り替えられます。Laravelが用意している3種類は、app/coinfig/view.phpの中の設定を変更し、切り替えます。

しかし、これらはCSSフレームワークのTwitter Bootstrapを利用しています。じゃあ、Bootstrap以外に切り替えられるのかと言えば、そのままでは無理で、多少工夫をしなくてはなりません。

今回、Foundationが新しいバージョンをリリースしたので、Foundation5に対応する実例をご覧ください。

ビューファイルの切り替え

Laravel4が用意しているビューファイルは、vendor/laravel/framework/src/Illuminate/Pagination/views/に存在しています。

もちろん、これらはFoundation5に対応していませんので、そのまま使えません。

通常のビューのように、app/viewsフォルダー下にビューを作成します。今回はapp/views/pagination/foundation5.phpファイルを作成します。

  1. <?php $presenter = new Foundation5Presenter( $paginator ); ?>
  2.  
  3. <?php if( $paginator->getLastPage() > 1 ): ?>
  4. <ul class="pagination">
  5. <?php echo $presenter->render(); ?>
  6. </ul>
  7. <?php endif; ?>

ペギネーションのビューファイルは、似たような構成になります。最初にプレゼンタークラスのインスタンスを取得し、そのrenderメソッドを呼び出しています。

今回作成したのは、Foundation5Presenterクラスです。このクラスは本来PSR-0に基づきローディングさせたほうが良いと思いますが、指定の手間を省くため、modelsディレクトリー下に作成しましょう。app/models/Foundation5Presenter.phpです。

  1. <?php
  2.  
  3. use Illuminate\Pagination\BootstrapPresenter;
  4.  
  5. /**
  6. * Foundation 5 presenter
  7. *
  8. * Override methods include hard coded html tags.
  9. */
  10. class Foundation5Presenter extends BootstrapPresenter{
  11.  
  12. /**
  13. * Create a range of pagination links.
  14. *
  15. * @param int $start
  16. * @param int $end
  17. * @return string
  18. */
  19. public function getPageRange($start, $end)
  20. {
  21. $pages = array();
  22.  
  23. for ($page = $start; $page <= $end; $page++)
  24. {
  25. // If the current page is equal to the page we're iterating on, we will create a
  26. // disabled link for that page. Otherwise, we can create a typical active one
  27. // for the link. These views use the "Twitter Bootstrap" styles by default.
  28. if ($this->currentPage == $page)
  29. {
  30. $pages[] = '<li class="current"><span>'.$page.'</span></li>';
  31. }
  32. else
  33. {
  34. $pages[] = $this->getLink($page);
  35. }
  36. }
  37.  
  38. return implode('', $pages);
  39. }
  40.  
  41. /**
  42. * Get the previous page pagination element.
  43. *
  44. * @param string $text
  45. * @return string
  46. */
  47. public function getPrevious($text = '&laquo;')
  48. {
  49. // If the current page is less than or equal to one, it means we can't go any
  50. // further back in the pages, so we will render a disabled previous button
  51. // when that is the case. Otherwise, we will give it an active "status".
  52. if ($this->currentPage <= 1)
  53. {
  54. return '<li class="allow unavailable"><span>'.$text.'</span></li>';
  55. }
  56. else
  57. {
  58. $url = $this->paginator->getUrl($this->currentPage - 1);
  59.  
  60. return '<li class="allow"><a href="'.$url.'">'.$text.'</a></li>';
  61. }
  62. }
  63.  
  64. /**
  65. * Get the next page pagination element.
  66. *
  67. * @param string $text
  68. * @return string
  69. */
  70. public function getNext($text = '&raquo;')
  71. {
  72. // If the current page is greater than or equal to the last page, it means we
  73. // can't go any further into the pages, as we're already on this last page
  74. // that is available, so we will make it the "next" link style disabled.
  75. if ($this->currentPage >= $this->lastPage)
  76. {
  77. return '<li class="allow unavailable"><span>'.$text.'</span></li>';
  78. }
  79. else
  80. {
  81. $url = $this->paginator->getUrl($this->currentPage + 1);
  82.  
  83. return '<li class="allow"><a href="'.$url.'">'.$text.'</a></li>';
  84. }
  85. }
  86.  
  87. /**
  88. * Get a pagination "dot" element.
  89. *
  90. * @return string
  91. */
  92. public function getDots()
  93. {
  94. return '<li class="unavailable"><span>...</span></li>';
  95. }
  96.  
  97. /**
  98. * Create a pagination slider link.
  99. *
  100. * @param mixed $page
  101. * @return string
  102. */
  103. public function getLink($page)
  104. {
  105. $url = $this->paginator->getUrl($page);
  106.  
  107. return '<li><a href="'.$url.'">'.$page.'</a></li>';
  108. }
  109.  
  110. }

Illuminate\Pagination\BootstrapPresenterを拡張していますが、実際、このクラス内にハードコードされている、HTMLのclass指定をFoundation5用に書き換えているだけです。

このプレゼンテーターにはインターフェイスが定義されていません。ですから、自由に自分の好きなように作成してもかまいません。要は、ペジネーション用のコードを生成できれば良いわけです。(ですから、自作する場合は、別段renderというメソッド名にこだわる必要もありません。)

これで準備が整いました。app/config/view.phpを変更し、最初に作成した'pagination.foundation5`をビューとして指定してください。Laravel4が提供しているビューを利用する場合は'pagination::...'と書きますが、自前のビューを利用する場合は、いつもビューを指定している通りに指定します。

これで、ペギネーションを利用すれば、Foundation5用に表示されます。(実際は、Bootstrapと大して違いが出ないのですけど。:D)

注意

多分、Foundation5はリリースされたばかりで、結構バグがあるようです。例えばcssにはペジネーションのactiveクラスの属性指定がないため、現在のページがデモのように表示されません。

対応されるまで、自分で指定する必要があります。

  1. ul.pagination li.current {
  2. background: none repeat scroll 0 0 #008CBA;
  3. color: #FFFFFF;
  4. cursor: default;
  5. font-weight: bold;
  6. padding: 0.05556rem 0.55556rem;
  7. border-radius: 3px;
  8. }

ペギネーションはとても難しい問題を含んでいます。それは、ペギネーションと書くとペジネーション派の人から揶揄され、ペジネーションと書くとペギネーション派の人からブーブー言われます。願わくば、こんなことで突っ込まれないように…(最初のぺは、あの英語の時間に習ったアとエの中間という音です。その後はじぇじぇじぇのジェですから、ペジェネイションかパジェネイションが正しいと、自分で突っ込んでおきましょう。ペァジェネイションかな?)

明日の担当も、私です。明後日はまだ誰も予約していません。この程度、これより簡単でも、使用感の感想でも良いので、書きたい方はどうぞ。