Zend_Navigation

http://framework.zend.com/manual/ja/zend.navigation.html

それなりに重要そうなのに日本語のドキュメントが無いっていう。

ここでは以下のような遷移を考えてみる

トップ (index/index)
     - コメント一覧 (comment/index)
         - コメント詳細 (comment/view/{id})

  - データ一覧 (index/index)
     - 子データ一覧 ({dataTitle}/index)
         - 子データ詳細 ({dataTitle/{childDataTitle/index}

書いててよくわからなくなってきたんで少し構造置いてみます。

Commentコントローラー

indexからリンクが貼られ、画面イメージ的には以下のようなものを想定する。

Zend_Navigationは実はサイト全ての構造を持ちうる事ができ、サイトマップ等自動的に描画する事ができるのだが、今回はあくまでBreadcrumb(パンくず、パスリンク、ナビリンク)の実装に留める。従って、表現に関しては常に水平的であり、垂直的な構造は今回は取り上げない。

さて、これを実現するCommentコントローラは以下の通り

application/controllers/CommentController.php

class CommentController extends Zend_Controller_Action
{
    private $_pages = array(
            array(
                'label' => 'Comment',
                'action' => 'index',
                'controller' => 'comment',
                'module' => 'default',
                'pages' => array(
                    array(
                        'label' => 'View',
                        'action' => 'view',
                        'controller' => 'comment',
                        'module' => 'default',
                        ),
                ),
            ),
    );
 
    public function init()
    {
    }
 
    public function indexAction()
    {
        $container = new Zend_Navigation($this->_pages);
        $this->view->navigation($container);
    }
 
    public function viewAction()
    {
        $container = new Zend_Navigation($this->_pages);
        $this->view->navigation($container);
    }
}

viewは適当な所でこんなものを埋めるだけ

<div>
  <?php echo $this->navigation()->breadcrumbs()->setSeparator(' &gt;&gt; ') ?>
</div>

output

がしかし、このやり方だとindexでリンクが出ないので、必要であればこのように指定して出してやる必要がある

<?php echo $this->navigation()->breadcrumbs()->setMinDepth(0) ?>

微修正

ここまででいろいろと問題があるわけだが、まずviewのリンクにはActiveになった時、該当のID項目を出したいとかいう話が出てくるはず。となるとLabelを変更する必要などが生じてくる。これには以下のようにして対応できる。

    public function viewAction()
    {
        $id = $this->getRequest()->getParam('id');
        $container = new Zend_Navigation($this->_pages);
        $container->findOneBy('label', 'View')->setLabel("View ID: $id");
        $this->view->navigation($container);
        $this->view->id = $id;
    }

他のコントローラも跨る包括的なページ設定

このような構造を取り入れると、かなり結合度が高くなってしまうので十分に考えて設計しなくてはいけないが、例えばCommentコントローラを考えれば、indexに繋がるものを書かなければならない。 それはそれでいいのだが、一々コントローラごとにページの設定を書くのも面倒な場合は、共通クラスを作成し、それを継承するようしてみるといった方法が考えられる。

例: controllers/Common.php

<?php
class CommonController extends Zend_Controller_Action
{
}
?>

それぞれのコントローラはCommonControllerを継承する

controllers/IndexController.php

require_once 'Common.php';
class IndexController extends CommonController
{
...

controllers/CommentController.php

require_once 'Common.php';
class CommentController extends CommonController
{
...

ページの設定はCommonのプロパティに持たせる。

    protected $_pages = array(
        array(
            'title'  => 'Home',
            'label'  => 'HOME',
            'action' => 'index',
            'controller' => 'index',
            'module' => 'default',
            'pages'  => array(
                array(
                    'title'  => 'Comment',
                    'label'  => 'Comment',
                    'action' => 'index',
                    'controller' => 'comment',
                    'module' => 'default',
                    'pages'  => array(
                        array(
                            'title'  => 'Comment',
                            'label'  => 'CommentView',
                            'action' => 'view',
                            'controller' => 'comment',
                            'module' => 'default',
                        )

うーむ、面倒になってきたのでソース置きます。

DBとか使ってないのでZFのパスが通っていればいけるはず。

zendframework/zend_nagivation.txt · 最終更新: 2012/04/07 10:32 (外部編集)
www.chimeric.de Creative Commons License Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0