前エントリの続き。
新たに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')}」などとしたいですね。