63日目:sfPagerでページング
Googleで検索した時に、ヒットした件数が多いと G o o o o g l eと表示されますが、あれがページングです。単に次のページへ案内するだけじゃなくて、先まで一気に飛べる便利なインターフェースです。あれを実装してみました。
symfonyには sfPropelPagerという便利なオブジェクトがあって、それを使えば一発なのですが、徹底攻略本を見ても、いまいち良く分かりませんでした。色々Webを見て回った結果、codezineさんの記事が一番わかりやすかったので、それを元に実装(というかコピペ)してみました(メソッド一覧があるのが嬉しかったです)。
思うに、フレームワークを使ったプログラミングで、あまり特殊な事をしない場合、プログラミングの8割がコピペで足りると思うのですが、どうでしょう? 自分の頭の中に沢山事例集を用意して、それを取ってくるだけで、大抵のケースは十分な気がします。僕は PHPの文法をちょっとしかしていませんが、コピペプログラミングだけでも、掲示板程度のアプリは作れてしまいます。最近のフレームワークの進歩にはびっくりです。
まずはアクション。今回は channelモジュールの listアクションに組み込んでみました。listアクションでパラメータをとる事ができるって初めて知りました(笑)。
/var/www/podtv/apps/frontend/modules/channel/actions/actions.class.php
public function executeList() { public function executeList() { // $this->channels = ChannelPeer::doSelect(new Criteria()); $c = new Criteria(); $pager = new sfPropelPager( 'Channel', 3); $pager->setCriteria( $c); $pager->setPage( $this->getRequestParameter( 'page', 1)); $pager->init(); $this->pager = $pager; } $c = new Criteria(); $pager = new sfPropelPager( 'Channel', 3); $pager->setCriteria( $c); $pager->setPage( $this->getRequestParameter( 'page', 1)); $pager->init(); $this->pager = $pager; }
コメントアウトした部分が symfonyで自動で作られたコードです。で、view。
/var/www/podtv/apps/frontend/modules/channel/templates/listSuccess.php
<?php if ( $pager->haveToPaginate()) { echo link_to( '《 ', 'channel/list?page=' .$pager->getFirstPage()); echo link_to( '< ', 'channel/list?page=' .$pager->getPreviousPage()); foreach ( $pager->getLinks() as $page) { echo ( $page == $pager->getPage()) ? $page : link_to( $page, 'channel/list?page=' .$page); if ( $page != $pager->getCurrentMaxLink()) { echo ' - '; } } echo link_to( ' > ', 'channel/list?page=' .$pager->getNextPage()); echo link_to( '》 ', 'channel/list?page=' .$pager->getLastPage()); echo '現在のページは' .$pager->getPage(); } ?>
pager以外の部分は、ほぼ symfonyが作ったコードのままなので、省略です。変更したのは、
<?php foreach ($pager->getResults() as $channel): ?>
↑で $channelsとあったのを $pager->getResults()に変更しただけです。あら簡単。
で、動いた結果がこれ。
http://podtvlabo.com/channel/list/page/3
これは、ヘルパーだかパーシャルだかコンポーネントだかにした方が楽そうですが、どれが一番良いのでしょう?
あと、モデルに書くようなコードをアクションにガンガン書いていますが、困る事ってあるのでしょうか?