10分ぐらいで学べるSymfony2 〜pager編〜
今回はSymfony2でpageを実装する際のやり方のメモとなります。
symfony1だとsfPager又はsfDoctrinePager オブジェクトが存在してpager機能を実装してたのですが
Symfony2だとそんな機能はコア機能にはないようです。
そこでPagerBundleというバンドルを利用してpager機能を実装しました。
(1)インストール
vender下にバンドルをインストールしてオートロードの設定をします。
# vender/bundles/MakerLabs下にインストールされます $ vi deps [PagerBundle] git=git://github.com/makerlabs/PagerBundle.git target=bundles/MakerLabs/PagerBundle # インストール $ php bin/vendors install # オートロードの設定を記述 $ vi app/autoload.php 'MakerLabs' => __DIR__.'/../vendor/bundles', $ vi app/AppKernel.php new MakerLabs\PagerBundle\MakerLabsPagerBundle(),
(2)データベースを利用しないページャ
データベースオブジェクトを利用しない形のページャの例
# ルーティング設定 $ vi src/Root/SiteBundle/Resources/config/routing.yml information: pattern: /information/{page} defaults: { _controller: RootSiteBundle:Information:index, page: 1 } # コントローラでは100個のデータを25個づつページングする設定 $ vi src/Root/SiteBundle/Controller/InformationController.php use MakerLabs\PagerBundle\Pager; use MakerLabs\PagerBundle\Adapter\ArrayAdapter; class InformationController extends Controller { public function indexAction($page) { $array = range(1, 100); $adapter = new ArrayAdapter($array); $pager = new Pager($adapter, array('page' => $page, 'limit' => 25)); return $this->render('RootSiteBundle:Information:index.html.twig', array( 'pager' => $pager )); } } # 数字をそのまま出力します。 $ vi src/Root/SiteBundle/Resources/views/Information/index.html.twig {% if pager.isPaginable %} {{ paginate(pager, 'information') }} {% endif %} {% for item in pager.getResults %} <p>{{ item }}</p> {% endfor %}
(3)データベースを利用したページャ
次はデータをデータベースから取ってくる場合になります。
# AdapterをDoctrineOrmAdapterへ変更 $ vi src/Root/SiteBundle/Controller/InformationController.php use MakerLabs\PagerBundle\Adapter\DoctrineOrmAdapter; class InformationController extends Controller { public function indexAction($page) { $em = $this->getDoctrine()->getEntityManager(); $qb = $em->getRepository('RootSiteBundle:Information')->createQueryBuilder('f'); $adapter = new DoctrineOrmAdapter($qb); $pager = new Pager($adapter, array('page' => $page, 'limit' => 5)); return $this->render('RootSiteBundle:Information:index.html.twig', array( 'pager' => $pager )); } # Infomartionテーブルのtitleを表示 $ vi src/Root/SiteBundle/Resources/views/Information/index.html.twig {% if pager.isPaginable %} {{ paginate(pager, 'information') }} {% endif %} {% for item in pager.getResults %} <p>{{ item.title }}</p> {% endfor %}
(4)データベースからのSQLをカスタマイズ
(3)では無条件で取得していますが、informationテーブルにはstart_dateカラムがあり、
掲載開始前のデータは省く必要があります。
そんな時のSQLをカスタマイズはQueryBuilderを使用します
$ vi src/Root/SiteBundle/Controller/InformationController.php $now = date('Y-m-d H:i:s'); $em = $this->getDoctrine()->getEntityManager(); $qb = $em->getRepository('RootSiteBundle:Information')->createQueryBuilder('i') ->where('i.start_date < :start_date') ->setParameter('start_date', $now) ->orderBy('i.start_date', 'DESC'); $adapter = new DoctrineOrmAdapter($qb); $pager = new Pager($adapter, array('page' => $page, 'limit' => 5)); return $this->render('RootSiteBundle:Information:index.html.twig', array( 'pager' => $pager ));
(5)表示をカスタマイズ
次ページとかpaginate部分の表示をカスタマイズしたい場合はテンプレートを修正します。
# paginate.html.twigを読込するように指定 $ vi src/Root/SiteBundle/Resources/views/Information/index.html.twig {% if pager.isPaginable %} {{ paginate(pager, 'information', {}, 'RootSiteBundle:Information:paginate.html.twig')) }} {% endif %} {% for item in pager.getResults %} <p>{{ item.title }}</p> {% endfor %} # これをベースに修正していきます $ vi src/Root/SiteBundle/Resources/views/Information/paginate.html.twig hoge <ul class="pager"> {% if pager.isFirstPage == false %} <li class="first"><a href="{{ paginate_path(route, pager.getFirstPage, parameters) }}">«</a></li> <li class="previous"><a href="{{ paginate_path(route, pager.getPreviousPage, parameters) }}">‹</a></li> {% endif %} {% for page in pager.getPages %} {% if page == pager.getPage %} <li class="selected"> <b>{{ page }}</b> </li> {% else %} <li> <a href="{{ paginate_path(route, page, parameters) }}">{{ page }}</a> </li> {% endif %} {% endfor %} {% if pager.isLastPage == false %} <li class="next"><a href="{{ paginate_path(route, pager.getNextPage, parameters) }}">›</a></li> <li class="last"><a href="{{ paginate_path(route, pager.getLastPage, parameters) }}">»</a></li> {% endif %} </ul>
参考
pagerバンドルのページ
http://symfony2bundles.org/makerlabs/PagerBundle
以上です。