2012年2月7日

Yii Framework: ビューでウィジェットのコードをシンプルに書くいくつかの方法


Yii のウィジェットは便利ですが、ビューで記述していると、プロパティの指定が多くなって、なんだかなぁと思うことがよくあります。以下は CJuiDatePicker の例ですが、1フォーム部品でこれだけのコードを書くのはちょっと避けたいところ。

<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model' => $model,
'attribute' => 'birth',
'language' => 'ja',
'options' => array(
'dateFormat' => 'yy-mm-dd',
'yearRange' => '-70:+0',
'changeYear' => 'true',
'changeMonth' => 'true',
'showButtonPanel' => 'true',
'showOn' => 'both',
'buttonImage' => '/images/calendar.png',
'buttonImageOnly' => 'true',
),
)); ?>
view raw _form.php hosted with ❤ by GitHub
ということで、対処方法として考えられるのは以下。
  • widgetFactory コンポーネントで初期値を指定しておく方法
  • ウィジェットの拡張
  • renderParticial を使う方法

まずは、widgetFactory コンポーネントで初期値を指定しておく方法。Yii はそれぞれのウィジェットのプロパティをあらかじめ protected/config/main.php で初期値として持たせておくことができます。いちいち同じようなプロパティを記述しなくて済むので便利です。

また、初期値の上書きもできるので、数多くのウィジェットを扱っている場合などには活躍しそうな機能です。以下は widgetFactory コンポーネントで CJuiDatePicker の初期値を設定している例です。場所は protected/config/main.php。この場合、例えばビューの _form.php では CJuiDatePicker::model, attribute プロパティのみ指定してやればOKになります。
<?php
return array(
...
'components' => array(
...
'widgetFactory' => array(
'widgets' => array(
'CJuiDatePicker' => array(
'language' => 'ja',
'options' => array(
'dateFormat' => 'yy-mm-dd',
'yearRange' => '-70:+0',
'changeYear' => 'true',
'changeMonth' => 'true',
'showButtonPanel' => 'true',
'showOn' => 'both',
'buttonImage' => '/images/calendar.png',
'buttonImageOnly' => 'true',
),
),
),
),
...
view raw main.php hosted with ❤ by GitHub

次にウィジェットの拡張。
これは、もともと存在するウィジェットクラスを拡張して使おうというものです。widgetFactory コンポーネントと同様に、初期値の上書きもでき、機能の拡張や実装の変更なども可能になります。以下は CJuiDatePicker クラスを拡張したものです。設置場所は特に決まりはありませんが、protected/components/widgets 下にします。
<?php
Yii::import('zii.widgets.jui.CJuiDatePicker');
/**
* MyDatePicker class file.
*/
class MyDatePicker extends CJuiDatePicker
{
/**
* @see CJuiDatePicker::language
*/
public $language = 'ja';
/**
* @see CJuiWidget::options
*/
public $options = array(
'dateFormat' => 'yy-mm-dd',
'yearRange' => '-70:+0',
'changeYear' => 'true',
'changeMonth' => 'true',
'showButtonPanel' => 'true',
'showOn' => 'both',
'buttonImage' => '/images/calendar.png',
'buttonImageOnly' => 'true',
);
}
この場合、_form.php では $this->widget('application.components.widgets.MyDatePicker', array(...))という感じで記述します。ウィジェットのパスに拡張したファイル名を指定して、あとは model, attribute プロパティのみ指定してやればOKになります。

最後にrenderParticialを使う方法。
これはちょっとどうかなと思いますが、手っ取り早い方法ではあります。「ウィジェットのプロパティなどは全く変更はしない」場合のみ、使えそうな感じではありますが、views 下など任意のディレクトリに部分的なコードファイルを作って、使いたいときに呼び出すという形です。

この場合、_form.php では echo $this->renderPartial('/etc/_datePicker', array(...)) という感じで記述します。
<?php $this->widget('zii.widgets.jui.CJuiDatePicker', array(
'model' => $model,
'attribute' => $attribute,
'language' => 'ja',
'options' => array(
'dateFormat' => 'yy-mm-dd',
'yearRange' => '-70:+0',
'changeYear' => 'true',
'changeMonth' => 'true',
'showButtonPanel' => 'true',
'showOn' => 'both',
'buttonImage' => '/images/calendar.png',
'buttonImageOnly' => 'true',
),
)); ?>
view raw _datePicker.php hosted with ❤ by GitHub

今回紹介した 3 つはそれぞれ、個々に影響せず使うこともできますが、widgetFactory コンポーネントをベースとして、拡張したウィジェットを使うこともできるので、そのへんは、どういう流れで設定していけば管理しやすいかなど考えながら、作っていくことになるかなと思います。また、これらの他にもこういう方法があるよ、などの意見も聞ければ幸いです。

参考リンク

0 件のコメント:

コメントを投稿