UnphptagViewRenderer作ってみた その2
前エントリの続き。
新たに3つのタグ *{}, @{}, @part{} をサポートしてみました。つっても置換を足しただけですが。
UnphptagViewRenderer.php
<?php /** * UnphptagViewRenderer * * configuration: * <pre> * array( * 'components'=>array( * ...... * 'viewRenderer'=>array( * 'class'=>'path.to.class.UnphptagViewRenderer', * ), * ), * ) * </pre> * * echo: * %{ Yii::app()->name} -> <?php echo Yii::app()->name; ?> * encode echo: * %%{Yii::app()->name} -> <?php echo CHtml::encode(Yii::app()->name); ?> * code: * #{ $name = Yii::app()->name } -> <?php $name = Yii::app()->name; ?> * comment: * *{**** comment ****} -> * renderPartial with PHP TAG: * @{'/parts/part1', $param} -> <?php $this->renderPartial('/parts/part1', $param); ?> * renderPartial whthout PHP TAG: * @part{'/parts/part1', $param} -> $this->renderPartial('/parts/part1', $param) * */ class UnphptagViewRenderer extends CViewRenderer { protected function generateViewFile($sourceFile, $viewFile) { $source = file_get_contents($sourceFile); file_put_contents($viewFile, $this->parse($source)); } protected function parse($s) { $s = preg_replace('/\*\{([\s\S]*?)\}/', '', $s); $s = preg_replace('/%%\{([\s\S]*?)\}/', '<?php echo CHtml::encode($1); ?>', $s); $s = preg_replace('/%\{([\s\S]*?)\}/', '<?php echo $1; ?>', $s); $s = preg_replace('/#\{([\s\S]*?)\}/', '<?php $1; ?>', $s); $s = preg_replace('/\@\{([\s\S]*?)\}/', '<?php $this->renderPartial($1); ?>', $s); $s = preg_replace('/\@part\{([\s\S]*?)\}/', '$this->renderPartial($1)', $s); return $s; } }
PlayFrameworkのカスタムテンプレートタグ
yiiから離れますが、PlayFrameworkのカスタムテンプレートタグは使えるなーという印象があります。Aタグを生成する小さなものから、そこそこ凝ったDIVブロックを生成するものまでテンプレート化していました。
一方、yiiではそこそこのものはテンプレートにしますが、小さいのまではテンプレートにしていない。この違いはなんだろう。
$this->renderPartial は長いです。小さいテンプレート達一つ一つに $this->renderPartial, $this->renderPartial, $this->renderPartial と書きたくない。これがテンプレート化しない原因の一つじゃないかと考えました。
前回はview上にあふれるPHPタグを減らしました。今回は $this->renderPartial を減らします。
@{}タグ
「@{}」は$this->renderPartial省略記法その1です。次のように使います。引数はrenderPartialと同じです。というか「@{'aaa', bbb, ccc}」を置換して「$this->renderPartial('aaa', bbb, ccc)」にしているだけ。
サンプルはyii/demos/blogです。ここには3つの $this->renderPartial がありました。
blog/protected/views/post/view.php
#{ $this->breadcrumbs=array( $model->title, ); $this->pageTitle=$model->title; } <?php // $this->renderPartial('_view', array( // 'data'=>$model, //)); ↓↓↓ ?> @{'_view', array('data'=>$model,)} <div id="comments"> #{if($model->commentCount>=1):} <h3> %{$model->commentCount>1 ? $model->commentCount . ' comments' : 'One comment'} </h3> <?php // $this->renderPartial('_comments',array( // 'post'=>$model, // 'comments'=>$model->comments, //)); ↓↓↓ ?> @{'_comments',array( 'post'=>$model, 'comments'=>$model->comments, )} #{endif;} <h3>Leave a Comment</h3> #{if(Yii::app()->user->hasFlash('commentSubmitted')):} <div class="flash-success"> %{Yii::app()->user->getFlash('commentSubmitted')} </div> #{else:} <?php //$this->renderPartial('/comment/_form',array( // 'model'=>$comment, //)); ↓↓↓ ?> @{'/comment/_form',array('model'=>$comment,)} #{endif;} </div><!-- comments -->
パラメータをarrayで包んで渡すのはイケてないですね。「@_view{compact('model')}」などどしたいところです。
@part{}
$this->renderPartial の省略記法その2です。
YiiのCDetailViewに複雑なHTMLを表示させたいとき
↑のように $this->renderPartial で生成した文字列を使う場合もあります。この場合、次のように書けます。勝手に引用してすみません。
<?php $this->widget('zii.widgets.CDetailView', array( 'data'=>$model, 'attributes'=>array( 'id', 'name', //'poor_content', // 文字列表示じゃかっこ悪い array( 'label'=>'Complex Content', 'type'=>'raw', 'value'=> @part{'_complex_content', array('data'=>$model,), true} ), ), )); ?>
こちらも「@_complex_content{compact('model')}」などとしたいですね。