Zend_Paginatorを使ってみた
使用バージョン:Ver1.7.6
比較的最近加わったライブラリであるZend_Paginatorを使用してみた。http://framework.zend.com/manual/ja/zend.paginator.html 公式マニュアル
フレームワーク側の準備をする
まずはインスタンス作成。他ライブラリと同様、直接インスタンス生成する方法と、Factoryパターンを利用する静的メソッドが用意されている。引数に渡すのは、ページネーションを行う元ネタの取得方法。
これをデータソースアダプタと言う。種類は以下。
アダプタ 説明 Array PHPの配列を使用します。 DbSelect Zend_Db_Select のインスタンスを使用し、配列を返します。 DbTableSelect Zend_Db_Table_Select のインスタンスを使用し、 Zend_Db_Table_Rowset_Abstract のインスタンスを返します。 これは、結果セットについての追加情報 (カラム名など) を提供します。 Iterator Iterator のインスタンスを使用します。 Null データのページ処理を管理する際に Zend_Paginator を使用しません。その場合でもページ処理コントロールの機能を使うことはできます。
とりあえず今回は配列を渡す事にした。
配列の中身は以下とする。
<?php $array = ( [0] => array( ['title'] => 'hoge' ['body'] => 'ほげほげほげ' ) [1] => array( ['title'] => 'piyo' ['body'] => 'ぴよぴよぴよ' ) [2] => array( ['title'] => 'fuga' ['body'] => 'ふがふがふが' ) 〜〜〜〜20ほど続く… );
直接アダプターにデータソースを渡してインスタンス生成する
<?php $paginator = new Zend_Paginator(new Zend_Paginator_Adapter_Array($array));
FactoryMethodパターンで生成する
<?php $paginator = Zend_Paginator::factory($array);
お好きな方で。
次に必要であればオプションの設定を行う。
メソッド 説明 setCurrentPageNumber 現在のページ番号を設定します (デフォルトは 1)。 setItemCountPerPage 1 ページに表示する項目の最大数を設定します (デフォルトは 10)。 setPageRange ページ処理コントロールに表示する項目の数を設定します (デフォルトは 10)。 注意: ほとんどの場合はこの値が正確に守られますが、 スクロール形式の場合はこの値を単なる指針あるいは開始値 (例: Elastic) としてしか使わないこともあります。 setView レンダリングを支援するために、ビューのインスタンスを設定します。
とりあえず、「ユーザが要求したページ番号をコントローラのアクション内で教えてやる必要がある」ので、setCurrentPageNumberメソッドを使用して設定する。
例えば、
http://exsample.com/info/drink/
といったURLにアクセスして、そこのページに用意されている検索フォームから検索した結果でページングを始めると仮定する。
イメージ的には、
http://exsample.com/info/drink/page/1 http://exsample.com/info/drink/page/2 …
といった具合に進んでくれるようにしてみる。
この場合、Zend_Controller_Router_Interfaceを使ってルーティングの設定を行う必要がある。
ルーターのセッティングはiniファイルから行ってみる。
router.ini
routes.info.type = "Zend_Controller_Router_Route" routes.info.route = "info/drink/:articleName/:page" routes.info.defaults.module = "default" routes.info.defaults.controller = "info" routes.info.defaults.action = "drink" routes.info.reqs.articleName = "page" routes.info.reqs.page = \d+
iniファイル設定したら、index.phpで以下のような感じでルーターの設定を行う。
<?php $router = $front->getRouter(); $router->addConfig(new Zend_Config_Ini('../application/config/router.ini', 'routes');
パスは適宜変更。
先ほどのpaginatorのインスタンスを作成した箇所に戻って、ユーザーが要求したページ番号をpaginatorに設定するオプションを記述する。
<?php $paginator->setCurrentPageNumber($this->_getParam('page'));
これで、URLでいうと、
/page/1
の部分のページ数パラメータを取得して、paginatorに与える事ができる。
続けてオプションの設定を行う。
<?php Zend_Paginator::setDefaultScrollingStyle('Sliding'); Zend_View_Helper_PaginationControl::setDefaultViewPartial('my_pagination_control.phtml'); $paginator->setView($this->view);
一行目で、ページネーターが表示する「現在位置」の表示方法を設定している。以下設定できる項目。
スクロール形式 説明 All すべてのページを返します。 総ページ数が比較的少なめのときなど、 ドロップダウンメニュー形式でページ選択をさせる際に便利です。 そのような場合は、利用できるすべてのページを 一度にユーザに見せることになるでしょう。 Elastic Google 風のスクロール形式で、 ユーザがページを移動するのにあわせて拡大・縮小します。 Jumping ユーザがページを進めるにつれて、 ページ番号が表示範囲の最後に向けて進んでいきます。 表示範囲を超えると、新しい範囲の最初の位置に移動します。 Sliding Yahoo! 風のスクロール形式で、 現在表示されているページが常にページ範囲の中央 (あるいは可能な限りそれに近い場所) にあるようにします。これがデフォルトの形式です。
一通り見てみたけど、とりあえずデフォルトのSlidingが感覚的に合ったのでそのまま使用。
二行目で設定しているのが、ページネーターのコントロール部分(prev 1 2 3 … next)のテンプレート。
とりあえず適当な名前で設定しておく。後でファイル作る。
三行目でViewオブジェクトへ表示する内容をまとめてセットしてるようである。
(※これでビューオブジェクトの設定はいらないのかと思ったら、下のように別で設定しないと動かなかった。)
<?php $this->view->paginator = $paginator;
さらに、この状態で3行目の $paginator->setView($this->view); をコメントアウトしてみても別に問題無く動いた。
ソース追ってみないとよく分からんところなので、とりあえずどちらも記述しておく。
ビュー側の準備をする
次に、ページネーターのコントロール部分のテンプレートを作る。<?php if ($this->pageCount): ?> <div class="paginationControl"> <!-- 前のページへのリンク --> <?php if (isset($this->previous)): ?> <a href="<?php echo $this->url(array('page' => $this->previous)); ?>"> < Previous </a> | <?php else: ?> <span class="disabled">< Previous</span> | <?php endif; ?> <!-- ページ番号へのリンク --> <?php foreach ($this->pagesInRange as $page): ?> <?php if ($page != $this->current): ?> <a href="<?php echo $this->url(array('page' => $page)); ?>"> <?= $page; ?> </a> | <?php else: ?> <?php echo $page; ?> | <?php endif; ?> <?php endforeach; ?> <!-- 次のページへのリンク --> <?php if (isset($this->next)): ?> <a href="<?php echo $this->url(array('page' => $this->next)); ?>"> Next > </a> <?php else: ?> <span class="disabled">Next ></span> <?php endif; ?> </div> <?php endif; ?>
以上、ドキュメントより丸パクリ。
これを、
views/scripts/my_pagination_control.phtml
として、scriptsディレクトリ直下に保存する。デフォルトではこの階層に探しにいくみたい。他にディレクトリ切って入れときたい場合は適宜 setDefaultViewPartial の設定パスを書き変えてあげれば良い。
次に、本体となるテンプレートに、表示内容の設定を行う。
<?php if (count($this->paginator)): ?> <ul> <?php foreach ($this->paginator as $key => $item): ?> <li><?php echo $item['title']; ?></li> <li><?php echo $item['body']; ?></li> <?php endforeach; ?> </ul> <?php endif; ?> <?php echo $this->paginator ?>
内容は書いてある通りで、配列を回して中身表示。
最後の一行の echo $this->paginator で、ページネーターコントロール部分を表示している。
後は、検索formタグのactionに、
<form action="/info/drink/page/1">
みたいに設定しておけばOK。
表示!
hoge ほげほげほげ piyo ぴよぴよぴよ fuga ふがふがふが < Previous | 1 | 2 | 3 | 4 | 5 | Next >
みたいに表示されたらOK。後はページ遷移してきちんとURLと表示内容が整合性取れてるか確認!
他のデータソースアダプタに関してはまた次の機会に。