Zend_Dojo_Formで簡単確認画面

http://d.hatena.ne.jp/noopable/20090124/1232802786
これの続きで。

もっとも基本的なフォーム遷移のパターンとしては、
入力フォーム・確認画面・完了画面
入力フォームは当然Zend_Formで作成するとして、確認画面をどうするか。
getValuesしてビュースクリプトでサクッと画面を作って遷移してもいいのだが、確認画面後は通常はアクションが待っているので、そこだけ別のビューを組み立てるのはあまり面白くない。

昨年の今頃

実は昨年の今頃、某ポータルサイト用にZendFrameworkで管理画面を作成したのだが、その時はまだZend_Formはリリースされていなかった。フォームのハンドリングから、ビューの作成までカスタムメイドで作ったのだが、当時Zend_Formがあったら、もう少し仕事は楽だっただろう。
そのときは、フォーム画面はフォーム毎のテンプレートだったので、ビューヘルパーでフォームのステータス毎に処理を変えるヘルパーを作ってもらい(若いバイトさん)それを利用した。この方式でも入力画面と確認画面の制作は一度で済む。
Zend_Cacheを使うことで、投稿画像のサムネールを引きまわしたのも印象的だった。これもビューヘルパー。

Zend_Form的解決

Zend_Formではデコレーターを利用するので、テンプレート一枚でビューヘルパーで切り替えというわけにはいかない。切り替えのポイントはデコレーター。
ところで、Zend_Form_Elementの最初のデコレーターはViewHelper Zend_Dojo_FormはDijitElementである。Gofのデコレーターパターン、テンプレートパターンとは違うのだが、ビューのレンダリングにおいては、テンプレート式とデコレーター式、それぞれに長短がある。Zend_Formのデコレーターでは最初に適用されるデコレーターが最初に要素をinputタグ等にレンダリングするのがデフォルト。最初に要素から生データを取り出してフォーム要素タグを育成する部分を要素タグを使わずに、単純にpでもspanでも軽く囲ってやればいいわけだ。

具体的には

まず、そういうヘルパー・デコレーターがないか探してみたが、Zend_FormにもZend_Dojo_Formにもないっぽい。この先追加されたらそれに切り替えるとして、とりあえず自分で作ったデコレーターで実装する。
そのためには、プラグインローダーに自分のデコレーターのパスを覚えさせる必要がある。

$this->addPrefixPath('My_Form_Decorator', 'Decorator', Zend_Form::DECORATOR);

あとは、タグをエスケープして改行をbrに変えるデコレーターを作って上書きしてやればいい。
Escapedデコレーターを自分のデコレーターディレクトリに配置。
Zend_Dojo_Formの要素の場合は、DijitElementがそれにあたるから、

$group->addElementDecorators(array(array(array('DijitElement' =>'Escaped'))));

array array array !
これでOK。validならプレビューっていう流れにしやすい。
Zend_Formを使っているならViewHelperを上書きしなければならない。
キー名が指定されていない場合は、クラス名がキー名に使われるという仕様を利用した形だ。
http://d.hatena.ne.jp/noopable/20090123/1232690745
ここで言及したZend_Form_Decorator_PrepareElementsを使うのと同じような形で、PrepareForPreviewみたいなデコレーターを作ってもよいかもしれない。

デコレーターキー名の工夫

自前のフレームワークレイヤーでは、最初にデコレーターをロードする部分をカスタマイズしておいて、array('core' => 'DijitElement')といった具合にキー名に仕様決めをしておけば、後から書き変える用途では重宝する。現状だと、Zend_Form用にはViewHelperデコレーターを上書きということになるのだが、array('core' => 'ViewHelper')というデフォルトデコレーター指定にしてあれば、プレビューへの切り替えは'core' => 'Preview'で済むわけだ。しかも、外身がテーブルだろうがdtddだろうが問題なく動作する。
他にも、デコレーターの役割ベースでキー名を指定しておけば、デコレーターを切り替えた実装でも適切に上書きしていくことができるだろう。
この部分、Zend_Form的には仕様を縛らずに利用者で好きに仕様を決めてよっていう基本姿勢が感じられてgood。