# dojo() ビューヘルパー

`dojo()` ビューヘルパーは Dojo 環境のセットアップを簡単に行うためのものです。 次のような機能があります。

- CDN あるいはローカルパスのどちらの Dojo を使用するかの指定

- カスタム Dojo モジュールへのパスの指定

- `dojo.require` 文の指定

- 使用する dijit スタイルシートテーマの指定

- `dojo.addOnLoad()` イベントの指定

`dojo()` ビューヘルパーの実装は、 プレースホルダの実装の一例です。 中で扱うデータセットはビューオブジェクトを超えて永続化され、 レイアウトスクリプトから直接 echo できます。

## dojo() ビューヘルパーの使用例

この例では、ローカルパスの Dojo を使うことを想定しています。 またいくつかの dijit を使い、Tundra dijit テーマを使用するものとします。

多くのページでは、開発者は Dojo をまったく使用しません。 そこで、Dojo が必要となるビュースクリプトやレイアウトスクリプトだけに注目し、 そこで Dojo 環境を用意してレンダリングすることにします。

まず、ビューオブジェクトに Dojo ビューヘルパーのパスを教えてやる必要があります。 これは、起動ファイルあるいは初期に実行されるプラグインで行います。 ビューオブジェクトを取得して次のコードを実行しましょう。

    $view->addHelperPath('Zend/Dojo/View/Helper/', 'Zend_Dojo_View_Helper');

次はビュースクリプトです。今回の例では、 FilteringSelect を使うことにします。 これは QueryReadStore を継承したカスタムストアを使用します。 今回の例ではこれは 'PairedStore' という名前で、 'custom' モジュールに格納します。

    <?php // FilteringSelect 用のデータストアの設定 ?>
    <div dojoType="custom.PairedStore" jsId="stateStore"
        url="/data/autocomplete/type/state/format/ajax"
        requestMethod="get"></div>

    <?php // 入力要素 ?>
    State: <input id="state" dojoType="dijit.form.FilteringSelect"
        store="stateStore" pageSize="5" />

    <?php // 必須 dojo 要素の設定
    $this->dojo()->enable()
                 ->setDjConfigOption('parseOnLoad', true)
                 ->registerModulePath('custom', '../custom/')
                 ->requireModule('dijit.form.FilteringSelect')
                 ->requireModule('custom.PairedStore'); ?>

レイアウトスクリプトでは、 まず Dojo が有効になっているかどうかを調べ、 有効ならさらに設定を行ってそれを使用します。

    <?php echo $this->doctype() ?>
    <html>
    <head>
        <?php echo $this->headTitle() ?>
        <?php echo $this->headMeta() ?>
        <?php echo $this->headLink() ?>
        <?php echo $this->headStyle() ?>
    <?php if ($this->dojo()->isEnabled()){
        $this->dojo()->setLocalPath('/js/dojo/dojo.js')
                     ->addStyleSheetModule('dijit.themes.tundra');
        echo $this->dojo();
       }
    ?>
        <?php echo $this->headScript() ?>
    </head>
    <body class="tundra">
        <?php echo $this->layout()->content ?>
        <?php echo $this->inlineScript() ?>
    </body>
    </html>

これで、各ファイルが正しい場所にありさえすれば FilteringSelect を使った処理ができるようになりました!

## デフォルトで使用される UTF-8 エンコーディング

By default, Zend Framework uses UTF-8 as its default encoding, and, specific to this case, `Zend_View` does as well. Character encoding can be set differently on the view object itself using the `setEncoding()` method (or the the encoding instantiation parameter). However, since `Zend_View_Interface` does not define accessors for encoding, it's possible that if you are using a custom view implementation with the Dojo view helper, you will not have a `getEncoding()` method, which is what the view helper uses internally for determining the character set in which to encode.

If you do not want to utilize UTF-8 in such a situation, you will need to implement a `getEncoding()` method in your custom view implementation.

## プログラム的および宣言的な Dojo 使用法

Dojo の機能の多くは、宣言的 (declarative) な方法および プログラム的 (programmatic) な方法の両方で使用できます。 宣言的 な使用法とは、 標準の HTML 要素に対して非標準の属性を指定し、 ページの読み込み時にそれをパースするというものです。 これは強力でシンプルな構文のため使用しやすいのですが、 ページの検証時に問題を起こす可能性があります。

プログラム的 な使用法とは、 既存の要素を ID もしくは CSS セレクタで取得し、 それを Dojo の適切なオブジェクトのコンストラクタに渡すというものです。 非標準の HTML 属性を使うことはないので、ページの検証はうまくいきます。

実際のところ、どちらの手法を用いたとしても、 javascript が無効になっていたり Dojo スクリプトリソースが使用できなかったりした場合に機能が低下してしまいます。 標準規格とドキュメントの検証を優先させるため、Zend Framework ではプログラム的な使用法をデフォルトとしています。 さまざまなビューヘルパーが javascript を生成してそれを `dojo()` ビューヘルパーに渡し、レンダリング時に読み込むのです。

この方法を使うと、さまざまなオプションを使用して プログラム上で独自のデコレーションを行うことができます。 たとえば dijit イベントのハンドラを指定することなども可能です。

そのために、宣言的な構文の機能以外にも多くの静的メソッドが用意されており、 全体の振る舞いを設定できます。

### 宣言的、あるいはプログラム的な Dojo の使用法の指定

宣言的な使用法を指定するには、静的メソッド `setUseDeclarative()` をコールします。

    Zend_Dojo_View_Helper_Dojo::setUseDeclarative();

プログラム的な使用法を指定するには、静的メソッド `setUseProgrammatic()` をコールします。

    Zend_Dojo_View_Helper_Dojo::setUseProgrammatic();

独自のプログラム的なルールを作成したい場合は、 プログラム的な使用法を指定する際に値 '-1' を渡す必要があります。この場合、 dijit を装飾するための javascript は生成されません。

    Zend_Dojo_View_Helper_Dojo::setUseProgrammatic(-1);

## テーマ

Dojo では、dijits (widgets) 用のテーマを作成できます。 テーマを選択するにはモジュールパスにそれを渡します。

    $view->dojo()->addStylesheetModule('dijit.themes.tundra');

モジュールパスの検索は、'.' をディレクトリ区切り文字として使用し、 リストの最後の名前を CSS ファイルと見て行います。上の例では、Dojo は '`dijit/themes/tundra/tundra.css`' のテーマを探します。

テーマを使う際に重要なのは、使用するすべての dijit について、それを囲むコンテナにテーマのクラスを指定することです。 もっともよくある例は、body に指定するものです。

    <body class="tundra">

## レイヤーの使用 (カスタムビルド)

デフォルトでは、`dojo.require` ステートメントを使用すると dojo はサーバにリクエストを返し、適切な javascript ファイルを取得します。 たくさんの dijit を使用する場合は、大量のリクエストがサーバに届くことになります。 これはちょっと無駄ですね。

これに対する Dojo からの回答はとして用意したのが カスタムビルド です。これは、次のようなことを行います。

- 必要なファイルを レイヤー にまとめます。 レイヤーは、すべての必要なファイルをひとつの JS ファイルにまとめたものです (これが、このセクションの名前の由来です)。

- digit が使用する javascript 以外のファイル (テンプレートファイルなど) をまとめます。 これらもまた、レイヤーとして同じ JS ファイルにまとめられます。

- そのファイルを ShrinkSafe に渡します。 これは、空白文字やコメントを削除して変数名を短くします。

中にはレイヤー化できないファイルもありますが、 ビルドの際にリリース用のディレクトリが作成され、 レイヤーファイルとその他のすべてのファイルが格納されます。 これにより、あなたの作成するサイトやアプリケーションが 必要とするだけの内容に最適化した内容を配布できます。

レイヤーを使うために、`dojo()` ビューヘルパーには `addLayer()` メソッドが用意されており、 これで必要なレイヤーへのパスを追加します。

    $view->dojo()->addLayer('/js/foo/foo.js');

独自のビルドを作成するためのさらなる情報は、 Dojo のビルドのドキュメントを参照ください。

## 使用できるメソッド

`dojo()` ビューヘルパーは常に、 dojo プレースホルダコンテナのインスタンスを返します。 このコンテナオブジェクトで使用できるメソッドは次のとおりです。

- `setView(Zend_View_Interface $view)`: コンテナ内のビューインスタンスを設定します。

- `enable()`: Dojo 統合機能を明示的に有効化します。

- `disable()`: Dojo 統合機能を無効化します。

- `isEnabled()`: Dojo 統合機能が有効かどうかを調べます。

- `requireModule($module)`: `dojo.require` 文を作成します。

- `getModules()`: どのモジュールが必要なのかを調べます。

- `registerModulePath($module, $path)`: 独自の Dojo モジュールのパスを登録します。

- `getModulePaths()`: 登録済みのモジュールパスの一覧を取得します。

- `addLayer($path)`: 使用するレイヤー (カスタムビルド) のパスを追加します。

- `getLayers()`: 登録済みのすべてのレイヤー (カスタムビルド) のパスの一覧を取得します。

- `removeLayer($path)`: `$path` にマッチするレイヤー (カスタムビルド) を、 登録済みレイヤーの一覧から削除します。

- `setCdnBase($url)`: CDN 用のベース URL を設定します。一般的には `Zend_Dojo::CDN_BASE_AOL` あるいは `Zend_Dojo::CDN_BASE_GOOGLE` となりますが、これはバージョン番号より前に URL 文字列に必要となります。

- `getCdnBase()`: 使用するベース CDN の URL を取得します。

- `setCdnVersion($version = null)`: CDN から使用する Dojo のバージョンを設定します。

- `getCdnVersion()`: CDN からどのバージョンの Dojo を使用しているかを取得します。

- `setCdnDojoPath($path)`: CDN 上のファイル `dojo.js` あるいは `dojo.xd.js` への相対パスを設定します。一般的には `Zend_Dojo::CDN_DOJO_PATH_AOL` あるいは `Zend_Dojo::CDN_DOJO_PATH_GOOGLE` となりますが、これはバージョン番号の後の URL 文字列に必要となります。

- `getCdnDojoPath()`: dojo.js ファイルを指す、CDN url のパスの最後の部分を取得します。

- `useCdn()`: コンテナに、CDN を使用するよう指定します。暗黙的に統合機能を有効化します。

- `setLocalPath($path)`: コンテナに、ローカルの Dojo インストールパスを指定します (サーバからの相対パスで、かつ `dojo.js` ファイル自体も含まなければなりません)。 暗黙的に統合機能を有効化します。

- `getLocalPath()`: どのローカルパスの Dojo を使用しているかを取得します。

- `useLocalPath()`: 統合機能がローカルパスの Dojo を使用しているかどうかを調べます。

- `setDjConfig(array $config)`: dojo または dijit の設定項目を設定します (連想配列で指定します)。

- `setDjConfigOption($option, $value)`: 単一の dojo または dijit 設定項目を設定します。

- `getDjConfig()`: すべての dojo または dijit 設定値を取得します。

- `getDjConfigOption($option, $default = null)`: 単一の dojo または dijit 設定値を取得します。

- `addStylesheetModule($module)`: モジュールのテーマに基づいたスタイルシートを追加します。

- `getStylesheetModules()`: モジュールのテーマとして登録されたスタイルシートを取得します。

- `addStylesheet($path)`: Dojo で使用するローカルスタイルシートを追加します。

- `getStylesheets()`: ローカル Dojo スタイルシートを取得します。

- `addOnLoad($spec, $function = null)`: `dojo.onLoad` がコールするラムダ関数を追加します。 引数をひとつわたした場合は、 関数名あるいは javascript のクロージャと見なされます。 引数をふたつわたした場合は、 最初の引数がオブジェクトのインスタンスを表す変数名、 二番目の引数がそのオブジェクトのメソッド名あるいは そのオブジェクトで使用するクロージャと見なされます。

- `prependOnLoad($spec, $function = null)`: `addOnLoad()` と同じですが、onLoad スタックの先頭に追加するという点だけが異なります。

- `getOnLoadActions()`: コンテナに登録されているすべての `dojo.onLoad()` アクションを取得します。 これは配列の配列となります。

- `onLoadCaptureStart($obj = null)`: `dojo.onLoad()` のラムダ関数として使用するデータをキャプチャします。 `$obj` が指定された場合は、キャプチャされた JS コードはその Javascript オブジェクトで使用するクロージャであると見なします。

- `onLoadCaptureEnd($obj = null)`: `dojo.onLoad()` で使用するデータのキャプチャを終了します。

- `javascriptCaptureStart()`: 任意の javascript をキャプチャし、Dojo JS (onLoad や require など) として取り込めるようにします。

- `javascriptCaptureEnd()`: javascript のキャプチャを終了します。

- `__toString()`: コンテナを文字列にキャストします。すべての HTML style 要素および script 要素をレンダリングします。