<?xml version="1.0" encoding="UTF-8"?>
<!-- Reviewed: no -->
<!-- EN-Revision: 24249 -->
<sect1 id="zend.controller.modular">
    <title>モジュラーディレクトリ構造の規約の使用</title>

    <sect2 id="zend.controller.modular.introduction">
        <title>導入</title>

        <para>
            モジュラーディレクトリ構造の規約 (The Conventional Modular directory structure)
            により、さまざまな <acronym>MVC</acronym> アプリケーションを自己完結した単位にまとめることができます。
            また、それをさまざまなフロントコントローラで再利用できるようになります。
            このディレクトリ構造は、次のようになります。
        </para>

        <programlisting language="txt"><![CDATA[
docroot/
    index.php
application/
    default/
        controllers/
            IndexController.php
            FooController.php
        models/
        views/
            scripts/
                index/
                foo/
            helpers/
            filters/
    blog/
        controllers/
            IndexController.php
        models/
        views/
            scripts/
                index/
            helpers/
            filters/
    news/
        controllers/
            IndexController.php
            ListController.php
        models/
        views/
            scripts/
                index/
                list/
            helpers/
            filters/
]]></programlisting>

        <para>
            この考え方では、モジュール名が、
            その中に含まれるコントローラのプレフィックスとなります。
            上の例には、三つのモジュールコントローラ
            '<classname>Blog_IndexController</classname>'、'<classname>News_IndexController</classname>' および
            '<classname>News_ListController</classname>' が含まれます。また、グローバルコントローラも
            '<classname>IndexController</classname>' と '<classname>FooController</classname>' の二つが定義されています。
            これらは名前空間に属しません。この章のサンプルでは、
            ここで示したディレクトリ構造を使用します。
        </para>

        <note>
            <title>デフォルトモジュールでは名前空間を使用しない</title>

            <para>
                デフォルトモジュールでは、コントローラは
                名前空間プレフィックスを必要としないことに注意しましょう。
                したがって、上の例ではデフォルトモジュールのコントローラには
                'Default_' は不要です。そのベースコントローラ名である
                '<classname>IndexController</classname>' および
                '<classname>FooController</classname>' にもとづいて単純にディスパッチされます。
                しかし、それ以外のモジュールでは名前空間プレフィックスを使用します。
            </para>
        </note>

        <para>
            それでは、Zend Framework の <acronym>MVC</acronym> コンポーネントを使用して
            これらのディレクトリ配置を実装するにはどうすればいいのでしょうか?
        </para>
    </sect2>

    <sect2 id="zend.controller.modular.directories">
        <title>モジュールコントローラディレクトリの指定</title>

        <para>
            モジュールを使用するための第一歩となるのが、
            フロントコントローラでのコントローラディレクトリの設定方法を変更することです。
            基本的な <acronym>MVC</acronym> 版では、配列あるいは文字列を
            <methodname>setControllerDirectory()</methodname> に渡すか、
            あるいはパスを <methodname>addControllerDirectory()</methodname>
            に渡していました。モジュールを使用する場合は、
            これらのメソッドコールを少々変更する必要があります。
        </para>

        <para>
            <methodname>setControllerDirectory()</methodname> では、連想配列を渡す必要があります。
            連想配列のキーにはモジュール名、そしてその値としてディレクトリのパスを指定します。
            特別な名前 <property>default</property> をキーにすると、グローバルコントローラ
            (モジュール名前空間を必要としないもの) を指定できます。
            すべてのエントリは、ひとつのパスをさす文字列のキーを含まなければなりません。
            また、<property>default</property> というキーが必ず存在しなければなりません。
            次の例のようになります。
        </para>

        <programlisting language="php"><![CDATA[
$front->setControllerDirectory(array(
    'default' => '/path/to/application/controllers',
    'blog'    => '/path/to/application/blog/controllers'
));
]]></programlisting>

        <para>
            <methodname>addControllerDirectory()</methodname> では、オプションの二番目の引数を受け付けます。
            モジュールを使用する際には、モジュール名を二番目の引数で渡します。
            指定しない場合は、そのパスは <emphasis>default</emphasis> 名前空間に追加されます。
            次の例のようになります。
        </para>

        <programlisting language="php"><![CDATA[
$front->addControllerDirectory('/path/to/application/news/controllers',
                               'news');
]]></programlisting>

        <para>
            結局のところ、モジュールのディレクトリを設定する一番お手軽な方法は、
            共通のモジュールディレクトリの配下に同じ構造でモジュールを保持しておくことです。
            これを行うのが <methodname>addModuleDirectory()</methodname> メソッドです。
        </para>

        <programlisting language="php"><![CDATA[
/**
 * 次のような構造を想定しています
 * application/
 *     modules/
 *         default/
 *             controllers/
 *         foo/
 *             controllers/
 *         bar/
 *             controllers/
 */
$front->addModuleDirectory('/path/to/application/modules');
]]></programlisting>

        <para>
            上の例は <emphasis>default</emphasis>、
            <emphasis>foo</emphasis> および <emphasis>bar</emphasis> というモジュールを定義しており、
            それぞれのモジュール内に <filename>controllers/</filename>
            ディレクトリを保持しています。
        </para>

        <para>
            モジュール内のコントローラディレクトリ名を変更するには、
            <methodname>setModuleControllerDirectoryName()</methodname> を使用します。
        </para>

        <programlisting language="php"><![CDATA[
/**
 * コントローラのディレクトリを、次のように 'con' に変更します
 * application/
 *     modules/
 *         default/
 *             con/
 *         foo/
 *             con/
 *         bar/
 *             con/
 */
$front->setModuleControllerDirectoryName('con');
$front->addModuleDirectory('/path/to/application/modules');
]]></programlisting>

        <note>
            <para>
                モジュール内でコントローラディレクトリを使用しない場合は、
                <methodname>setModuleControllerDirectoryName()</methodname>
                に空の文字列を指定します。
            </para>
        </note>
    </sect2>

    <sect2 id="zend.controller.modular.router">
        <title>モジュールへのルーティング</title>

        <para>
            <classname>Zend_Controller_Router_Rewrite</classname> のデフォルトのルートは
            <classname>Zend_Controller_Router_Route_Module</classname> 型のオブジェクトです。
            このルートは、以下のいずれかの形式のルーティングを行います。
        </para>

        <itemizedlist>
            <listitem><para><code>:module/:controller/:action/*</code></para></listitem>
            <listitem><para><code>:controller/:action/*</code></para></listitem>
        </itemizedlist>

        <para>
            言い換えると、これは、指定したコントローラとアクション
            あるいはその先頭にモジュールをつけたものにマッチします。
            このマッチング規則からわかることは、
            フロントコントローラとディスパッチャに渡された配列で指定した
            コントローラディレクトリの配列に同名のキーがある場合にのみ
            モジュールにマッチするということです。
        </para>
    </sect2>

    <sect2 id="zend.controller.modular.defaultcontroller">
        <title>モジュールあるいはグローバルのデフォルトコントローラ</title>

        <para>
            デフォルトのルータでは、コントローラが <acronym>URL</acronym> で指定されなかった場合には
            デフォルトのコントローラ (特に指定しなければ <classname>IndexController</classname>)
            を使用します。モジュール対応のコントローラにおいて、
            モジュールのみを指定してコントローラを指定しなかった場合は、
            ディスパッチャはまず最初にモジュールパス内のデフォルトコントローラを探します。
            次に、グローバル名前空間 'default' にあるデフォルトコントローラを探します。
        </para>

        <para>
            デフォルトは常にグローバル名前空間のほうにしたい場合は、
            フロントコントローラでパラメータ
            <varname>$useDefaultControllerAlways</varname> を指定します。
        </para>

        <programlisting language="php"><![CDATA[
$front->setParam('useDefaultControllerAlways', true);
]]></programlisting>
    </sect2>
</sect1>
<!--
vim:se ts=4 sw=4 et:
-->
