PHP勉強会ネタ。複合ビューってのは、Viewのheaderとかfooterが分離してるようなの(?)
まずViewが実際にtemplateを出力してるのは、Ethna_ViewClass.phpの
function forward() { $renderer =& $this->_getRenderer(); $this->_setDefault($renderer); $renderer->perform($this->forward_path); }
これ。
まあこの3行を呼べばとりあえず描画される。
とりあえず、複数のViewClassを結合して1つのViewClassになるようにする。このため、
- 骨格
- 骨格の内部
の2つのViewClassが必要となる。
PHP勉強会でらいあさんがやってた方法(http://events.php.gr.jp/event.php/event_show/15でスライドとソースが見れるよ!行ってない人もチェキ/ってかここリンクされてるよ!)は、骨格部分を設定変数にしてしまう方法だけど、微妙に面倒な気がしたので、ちょっといじる。
設定は、各ViewClassのメンバに以下のように記述する。
var $layout = array( 'sidebar' => 'menu', 'body' => 'list', );
ハッシュの名前部分が変数名になり、値部分がViewの名前(Actionのreturnで渡す名前と同一)とする。
あとはこれを定義したViewのtemplateで
{$layout.sidebar} {$layout.body}
とかすればいい。もちろんSmartyなので普通のHTMLも入れれる。
これを実装するにはAPPID_ViewClass.phpに
function forward() { $renderer =& $this->_getRenderer(); $this->_setDefault($renderer); if (property_exists($this, 'layout')) { $ctl = $this->backend->controller; $layout_vars = array(); foreach($this->layout as $key=>$forward_name) { $view_class_name = $ctl->getViewClassName($forward_name); $view =& new $view_class_name($this->backend, $forward_name, $ctl->_getForwardPath($forward_name)); ob_start(); $view->preforward(); $view->forward(); $layout_vars[$key] = ob_get_contents(); ob_end_clean(); } $renderer->setProp('layout', $layout_vars); } $renderer->perform($this->forward_path); }
とする。
この方式は汎用性はあるものの、DRYっぽくない(骨格情報だらけになる)ので、Actionから呼ばれたViewは、コンテンツのメイン情報だけ入るようにして、ヘッダとかは勝手に入ってくる方式のほうが綺麗だと思う。結局Railsっぽくなるんだけど。rhacoのソースはまだ読んでない。