Zend Framework - Zend_Navigation編

HOME | TOP

■ 概要


HTML文書では、あるページ上から他ページに移動するためにリンクを使います。

<a href="/go/to/next/page.html" title="PHP超絶激鬼まとめ">PHPまとめ</a>


ご存知<a>タグを使えばこれができます。

つまりページごとに決まったURLアドレスというものを持っているわけです。

このことから、各ページごとに

URLアドレス = /go/to/next/page.html
タイトル       = PHP超絶激鬼まとめ
表示ラベル     = PHPまとめ


という風に情報をまとめておけば、いろんなことに利用できるようになります。

Zend_Navigationでは、個々の情報を持つページをオブジェクト化してまとめた入れ物を『コンテナ』と呼びます。
つまり全ページ分の情報をコンテナにまとめておけば、そのサイトに関するいろんなリンクを描けることになります。

コンテナにまとめたページを扱えるので、サイト内に限らず外部リンク先をまとめておけばリンク集を作ったりも当然できます。



[1] メニュー作り
そのサイトのメニューをボタン風にしたり、
■ ホーム
□ Zend Framework
□ PHPまとめ
□ サイトマップ
□ リンク集

またはリンクで枝分かれにしたりすることができるようになります。
  • ホーム
  • Zend Framework
    • MVCアプリケーション
    • コンポーネント解説
      • Zend_View編
      • Zend_Controller編
      • Zend_Navigation編
  • PHPまとめ
  • サイトマップ
  • リンク集



[2] パンくず作り
いわゆる「パンくず」と呼ばれるものを作ることができます。
サイト上部などに以下のような表示を用意することで、
ホームZend Frameworkコンポーネント > Zend_Navigation編

今見ているページがどこなのかをナビゲーションするのに有効です。

[3] サイトマップ作り
このサイトマップは主に検索エンジンにサイト構造を知らせるためのものです。


■ ページ情報の作成


1ページの情報は、連想配列を使って以下のように書くことができます。

これはちょうど<a>タグの持つ属性と一致します。
リンク情報なので、"uri"と"label"以外だったら省略も可能でしょう。

<a href="/go/to/next/page.html" title="PHP超絶激鬼まとめ" target="_self">PHPまとめ</a>


これが複数ページだと連想配列も複数ということになるので、連想配列を要素に持つ配列を作成することになります。

$pages = array(
    連想配列,
    連想配列,
    連想配列,
);

         ↓

$pages = array(
    array(
        'uri'   => '/go/to/next/page.html',
        'title' => 'PHP超絶激鬼まとめ',
        'label' => 'PHPまとめ'
    ),
    array(
        'uri'   => '/foo/bar.html',
        'title' => 'ラリホーの唱え方',
        'label' => '寝不足解消ページ'
    ),
    array(
        'uri'   => 'http://www.google.co.jp/',
        'title' => 'ぐーぐる',
        'label' => 'Google'
    ),
);


上記では、横並びの同じ階層のページ情報を配列にしています。

あるページの下の階層に属するページがあることも考えられます。
その場合は"pages"キーを使って作成します。

$pages = array(
    array(
        'uri'   => '/go/to/next/page.html',
        'title' => 'PHP超絶激鬼まとめ',
        'label' => 'PHPまとめ'
        'pages' => array(
            array(
                'uri'   => '/go/to/next/page2.html',
                'title' => 'PHP超絶激鬼まとめ',
                'label' => '関数'
            )
        )
    ),
    array(
        'uri'   => '/foo/bar.html',
        'title' => 'ラリホーの唱え方',
        'label' => '寝不足解消ページ'
    ),
    array(
        'uri'     => 'http://www.google.co.jp/',
        'title'   => 'ぐーぐる',
        'label'   => 'Google',
        'visible' => false,
        'order'   => -1
    ),
);


"pages"キーでサブページ情報を加えました。サブページは複数存在する場合もあるので"pages"キーの持つ値は単なる連想配列ではなく、連想配列を要素に持つ配列ということになります。

その他、"visible"キーを加えてfalse設定にすることで、表示対象から外すことができます。

それと、"order"キーで表示順を指定できます。配列情報なので基本はそのままの順番になりますが、順番を変えたい場合に使えます。



と、これまではMVC抜きでページ情報を作成していました。

MVCで扱うことを考えると、"uri"キーにURLアドレスをセットすることはどうやらしないようです。

その代わりに"module", "controller", "action"キーを設定することでリンク用URLアドレスに自動変換されるようになっています。

MVCの場合は開発時のURLアドレスを埋め込んでしまうと、モジュール化したときに設置する場所・階層によっては違うアドレスに変わってきてしまうので問題が起きないようにこのような指定方法にしたんだろうと推測します。

"uri"キーに"/モジュール名/コントローラ名/アクション名"で設定すると、モジュール化したときにドキュメントルート直下にフロントコントローラを設置しなかった場合に問題が起きるでしょう。

また、"モジュール名/コントローラ名/アクション名"で設定すると、リンクが表示されたページ階層によっては別階層を呼び出すことになってエラーになる恐れがあるということかなと推測します。



ということでMVCの場合は以下のような感じになりました。

$pages = array(
    array(
        'module'     => 'default',
        'controller' => 'index',
        'action'     => 'index',
        'title'      => 'ホームへGO',
        'label'      => 'ホーム'
    ),
    array(
        'module'     => 'default',
        'controller' => 'index',
        'action'     => 'links',
        'title'      => 'リンク集はコチラへ',
        'label'      => 'リンク集',
        'pages'      => array(
            array(
                'uri'     => 'http://www.google.co.jp/',
                'title'   => 'ぐーぐる',
                'label'   => 'Google',
                'target'  => '_blank',
            ),
            array(
                'uri'     => 'http://www.yahoo.co.jp/',
                'title'   => 'やふー',
                'label'   => 'Yahoo!',
                'target'  => '_blank',
            ),
            array(
                'uri'     => 'http://www.goo.ne.jp/',
                'title'   => 'ぐぅー',
                'label'   => 'goo',
                'target'  => '_blank',
            ),
        )
    ),
);

■ ページ情報をコンテナに登録


これまでは、複数のページ情報を配列にセットしていただけでした。
この配列を使って個々のページをオブジェクト化して、すべてのページオブジェクトをコンテナオブジェクトでまとめて管理するようにします。



必要なページをコンテナオブジェクトで管理できるようにするやり方は大きく分けて3つあります。

[1] コンテナオブジェクト作成とページ登録を一気に

require_once 'Zend/Navigation.php';

$container = new Zend_Navigation($pages); // 全ページ情報の配列を一気にコンテナに登録

渡したページ情報の配列は、内部でページオブジェクト化されて登録されるのでスッキリした分かり易いコードになります。



[2] コンテナオブジェクト作成後、setPages()メソッドで一気にページ登録

require_once 'Zend/Navigation.php';

$container = new Zend_Navigation();       // 先にコンテナオブジェクト作成
$container->setPages($pages);             // メソッドを使って全ページ情報を配列渡し

これも、渡したページ情報の配列が内部でページオブジェクト化されて登録されるのでシンプルです。

setPages()メソッドを使えば、コンテナオブジェクトの持つページ情報を別のページ情報に置き換えられるようになります。



[3] コンテナオブジェクト作成後、addPage()メソッドで1ページずつ分けて登録

require_once 'Zend/Navigation.php';

$container = new Zend_Navigation();       // 先にコンテナオブジェクト作成
$container->addPage($page1);              // 1ページ分の情報を持つ配列を登録
$container->addPage($page2);              // 別の1ページ分の情報を持つ配列を追加登録

1ページずつ分けて登録していきます。手数がかかるのであまり使わない方法だと思います。



その他、番外編としてページオブジェクト作成をしてからコンテナへの登録をしていくやり方があります。

[番外] ページオブジェクトを作成しては、コンテナオブジェクトへの追加登録を繰り返す

require_once 'Zend/Navigation/Page.php';
$page_obj1 = Zend_Navigation_Page::factory($page1); // 1つ目のページ情報を持つ配列をオブジェクト化
$page_obj2 = Zend_Navigation_Page::factory($page2); // 2つ目のページ情報を持つ配列をオブジェクト化

require_once 'Zend/Navigation.php';
$container = new Zend_Navigation();   // コンテナオブジェクト作成
$container->addPage($page_obj1);      // 1つ目のページオブジェクトを追加登録
$container->addPage($page_obj2);      // 2つ目のページオブジェクトを追加登録

手数がかかるのでこれは使いそうにありません。



以上でページ情報をコンテナオブジェクトにまとめて管理できるようにするまでが終わりました。

扱うページ情報をすべてコンテナオブジェクトに登録できたら次は描画するだけです。

Zend Frameworkでは例によってZend_Viewコンポーネントが描画を担当します。
コンテナオブジェクトの持つ情報を使って描画作業をしてくれるビューヘルパー$view->navigation()が用意されているのでこれを使っていくことになります。


■ コンテナに登録されたページ情報を描画する


まずはビューオブジェクトを作成してビューヘルパー$view->navigation()を使えるようにします。
このヘルパーにコンテナオブジェクトを登録して描画できるようにします。

require_once 'Zend/View.php';

$view = new Zend_View();
$view->setEncoding("sjis");         // SJISコード対応
$view->navigation($container);      // 描画対象のコンテナオブジェクトを登録
echo $view->navigation()->menu()->render();  // メニュー描画結果を表示


これでコンテナオブジェクト$containerの持つページ情報を、ビューヘルパーを使って描画することができました。

コンテナオブジェクトの登録方法はこれ以外にもあります。

$view->navigation($container);

としてコンテナを登録すると、内部でsetContainer()メソッドを使って実際の登録を行っているのでこれは

$view->navigation()->setContainer($container);

と書くこともできます。
また、メソッドチェーンが使えるので

$view->navigation($container)->menu()->render();

と書けばコンテナ登録と描画を一気にすることができます。



上記は、navigationビューヘルパーの機能のうちのメニューを描画しています。

メニュー以外の描画も同じ形式になります。

echo $view->navigation()->breadcrumbs()->render(); // パンくずリスト
echo $view->navigation()->sitemap()->render();     // サイトマップ




では実際に1つ作ってみましょう。

パンくずリストを表示させるために、無理やり"active"キーを配列にセットしています。
この"active"キーは、MVCのページオブジェクトに自動的に付加されるキーで、表示中のページはこの値がtrueになります。これを利用してここでは擬似的にパンくずリストを表示させています。



表示結果
[メニュー]

[パンくず]
HOMEHOME2HOME3>このページ自身


こんな感じになります。
navigationヘルパーのsetPartial()などを使えば更に複雑な処理やデコレーションができると思います。


2010(C)Mingw