テーマ

テーマはウェブアプリケーションのページの外観をカスタマイズするためのシステマティックな方法です。 新しいテーマを適用することで、ウェブアプリケーション全体のデザインを即座にドラマチックに変える事が出来ます。

Yii での各テーマは、ビューファイル、レイアウトファイル、画像や CSS や JavaScript などの関連するリソースで成り立ったディレクトリを表しています。 テーマの名前はそのディレクトリ名です。 全てのテーマは、WebRoot/themas という同じディレクトリの下に置かれます。 いかなる場合でも有効に出来るテーマは一つだけです。

ヒント: デフォルトのテーマディレクトリ WebRoot/themes は別のディレクトリに変更することが可能です。 themeManager アプリケーションコンポーネントの basePath プロパティと baseUrl プロパティを望むものに設定して下さい。

1. テーマを使う

テーマを有効にするには、ウェブアプリケーションのプロパティである theme の名前を望むものにセットします。 これは アプリケーション初期構成 の中か、コントローラアクションの処理の中のどちらでも行うことが可能です。

注意: テーマの名前は大文字小文字を区別します。 もしアクティブにしようとしたテーマが存在していない場合、Yii::app()->themenull を返します。

2. テーマを作成する

テーマディレクトリの中身は アプリケーションベースディレクトリ の中身と同様の方法で纏められなければなりません。 例えば、全てのビューファイルは views の中に置かれ、レイアウトビューファイルは views/layouts の中、システムビューファイルは views/system の中でなければいけません。 例えば、PostControllercreate ビューを classic テーマの中のビューで置き換えたい場合には、新しいファイルは、WebRoot/themes/classic/views/post/create.php に置きます。

モジュール の中のコントローラに対応するビューは、対応するテーマのビューもやはり views ディレクトリに置きます。 例えば、前記の PostControllerforum と呼ばれるモジュールの中にあるならば、WebRoot/themes/classic/views/forum/post/create.php として create ビューファイルを配置する必要があります。 もし、forum モジュールが他の support モジュールの中にある場合は、ビューファイルは WebRoot/themes/classic/views/support/forum/post/create.php となります。

注意: views ディレクトリは、セキュリティに関わるデータを含む事が有り得るため、ウェブユーザからのアクセスを防ぐ様に設定するべきです。

ビューを表示するために、renderrenderPartial をコールした際、結びついたビューファイルは、レイアウトファイルと同様に、現在アクティブになっているテーマの中から探されます。 そして見つかった場合は、それらのファイルがレンダリングされます。 そうでない場合は、viewPathlayoutPath で定められたデフォルトの場所へと探す場所が代替されます。

ヒント: 私たちはテーマビューの中で、他のテーマのリソースファイルへのリンクを必要とすることが度々あります。 例えば、あるテーマの images ディレクトリの中の画像を表示したい事があるでしょう。 現在アクティブになっているテーマの baseUrl プロパティを用いることで、下記の様に画像へのURLを生成する事が出来ます。

Yii::app()->theme->baseUrl . '/images/FileName.gif'

以下は、basicfancy という二つのテーマを持ったアプリケーションのディレクトリ構成例です。

WebRoot/
    assets
    protected/
        .htaccess
        components/
        controllers/
        models/
        views/
            layouts/
                main.php
            site/
                index.php
    themes/
        basic/
            views/
                .htaccess
                layouts/
                    main.php
                site/
                    index.php
        fancy/
            views/
                .htaccess
                layouts/
                    main.php
                site/
                    index.php

アプリケーション初期構成ファイルで以下のように構成します。

return array(
    'theme'=>'basic',
    ......
);

これで basic テーマが有効になります。 つまり、アプリケーションのレイアウトは themes/basic/views/layouts ディレクトリ下のものが使われ、サイトの index ビューは themes/basic/views/site にあるものが使われます。 ビューファイルがテーマの中に見つからなかった場合は、デフォルトの protected/views ディレクトリの下にあるものが使われます。

3. ウィジェットにテーマを適用する

バージョン 1.1.5 からは、ウィジェットによって使われるビューにもテーマを適用することが出来ます。 具体的に言うと、CWidget::render() を呼んでウィジェットのビューを表示するときに、Yii は要求されているビューファイルをウィジェットのビューフォルダーだけでなく、テーマフォルダーの下からも見つけ出そうと試みます。

Foo というクラス名のウィジェットの xyz ビューにテーマを適用するためには、まず、現在アクティブなテーマのビューフォルダの下に、Foo という (ウィジェットのクラス名と同じ) 名前のフォルダを作成します。 ウィジェットクラスが (PHP 5.3.0 以降でサポートされている) ネームスペースを持っている場合は、例えば \app\widgets\Foo であれば app_widgets_Foo という名前のフォルダを作成します。 つまり、ネームスペースのセパレータをアンダースコアで置き換えます。

次に、新しく作成されたフォルダの下に、xyz.php というビューファイルを作成します。 このため、現在のアクティブなテーマが basic である場合は、themes/basic/views/Foo/xyz.php というファイルを作成しなければなりません。 このファイルがオリジナルのビューの代りにウィジェットによって使用されます。

4. ウィジェットをグローバルにカスタマイズする

注意: この機能はバージョン 1.1.3 以降で利用できます。

サードパーティまたは Yii によって提供されているウィジェットを使用するときに、特定の要求にあわせてカスタマイズする必要があることがよくあります。 例えば、CLinkPager::maxButtonCount を 10 (デフォルト値) から 5 に変更したいことがあるでしょう。 これは、CBaseController::widget を呼んでウィジェットを作成するときに、プロパティの初期値を渡すことで実現できます。 しかし、CLinkPager を使用するすべての場所で同じカスタマイズを繰り返さなければならないとすれば、それは煩わしいことです。

$this->widget('CLinkPager', array(
    'pages'=>$pagination,
    'maxButtonCount'=>5,
    'cssFile'=>false,
));

グローバルなウィジェットカスタマイズ機能を利用すると、これらの初期値を一ヶ所だけ、すなわち、アプリケーション初期構成ファイルで設定すればよくなります。 これによって、ウィジェットのカスタマイズを管理しやすくなります。

グローバルなウィジェットカスタマイズ機能を使うためには、widgetFactory を以下のように構成する必要があります。

return array(
    'components'=>array(
        'widgetFactory'=>array(
            'widgets'=>array(
                'CLinkPager'=>array(
                    'maxButtonCount'=>5,
                    'cssFile'=>false,
                ),
                'CJuiDatePicker'=>array(
                    'language'=>'ru',
                ),
            ),
        ),
    ),
);

上記においては、CWidgetFactory::widgets プロパティを構成することによって、CLinkPager および CJuiDatePicker のグローバルなウィジェットカスタマイズを指定しています。 各ウィジェットのグローバルなカスタマイズは、配列の中の "キー-値" ペアによって表されています。 ここで、キーはウィジェットのクラス名であり、値はプロパティの初期値の配列です。

こうしておけば、CLinkPager ウィジェットをビューで生成する時には、いつでも、上記のプロパティ値がウィジェットに割り当てられるようになります。 そして、ビューでウィジェットを生成する時には、次のコードのように書くだけでよくなります。

$this->widget('CLinkPager', array(
    'pages'=>$pagination,
));

必要なときに初期プロパティ値をオーバーライドすることも引き続いて可能です。 例えば、あるビューにおいて maxButtonCount を 2 に設定したい場合は、次のようにすることが出来ます。

$this->widget('CLinkPager', array(
    'pages'=>$pagination,
    'maxButtonCount'=>2,
));

5. スキン

テーマを使用するとビューの外観を即座に変更できる一方で、スキンを使用するとビューで使用される widgets の外観を体系的にカスタマイズすることが出来ます。

スキンは、ウィジェットのプロパティ初期化に使用できる "名前-値" のペアの配列です。 スキンはウィジェットクラスに属するもので、ウィジェットクラスは名前で区別される複数のスキンを持つことが出来ます。 例えば、CLinkPager ウィジェットにひとつのスキンを与えて、その名前を classic とすることが出来ます。

スキン機能を使用するためには、まず、アプリケーション設定を変更して、widgetFactory アプリケーションコンポーネントの CWidgetFactory::enableSkin プロパティを true に構成しなければなりません。

return array(
    'components'=>array(
        'widgetFactory'=>array(
            'enableSkin'=>true,
        ),
    ),
);

バージョン 1.1.3 より前である場合は、ウィジェットのスキン機能を有効にするために下記の構成が必要になることに注意してください。

return array(
    'components'=>array(
        'widgetFactory'=>array(
            'class'=>'CWidgetFactory',
        ),
    ),
);

そして次に必要なスキンを作成します。 同一のウィジェットクラスに属するスキンは、ウィジェットのクラス名と同じ名前の単一の PHP スクリプトファイルに保存されます。 デフォルトでは、これらのスキンファイルはすべて protexted/views/skins ディレクトリに保存されます。 これを別のディレクトリに変更したい場合は、widgetFactory コンポーネントの skinPath プロパティを構成してください。 例として、protected/views/skins の下に CLinkPager.php という名前のファイルを作るとしましょう。 その内容は以下のようなものです。

<?php
return array(
    'default'=>array(
        'nextPageLabel'=>'次へ',
        'prevPageLabel'=>'前へ',
    ),
    'classic'=>array(
        'header'=>'',
        'maxButtonCount'=>5,
    ),
);

上記においては、CLinkPager のために二つのスキンを作成しています。defaultclassic です。 前者は、明示的に skin プロパティを指定しない場合に、すべての CLinkPager ウィジェットに適用されるスキンです。 後者は、skin プロパティが classic と指定された CLinkPager ウィジェットに適用されるスキンです。 例えば、以下のビューのコードにおいては、第一のページャは default スキンを使用し、第二のページャは classic スキンを使用します。

<?php $this->widget('CLinkPager'); ?>
 
<?php $this->widget('CLinkPager', array('skin'=>'classic')); ?>

ウィジェットを生成する際に初期プロパティ値を指定した場合は、そのプロパティ値が優先され、アプリケーションのスキンと結合されます。 例えば、下記のビューのコードが生成するページャの初期値は、array('header'=>'', 'maxButtonCount'=>6, 'cssFile'=>false) となりますが、それはビューで指定された初期プロパティ値と classic スキンを結合した結果です。

<?php $this->widget('CLinkPager', array(
    'skin'=>'classic',
    'maxButtonCount'=>6,
    'cssFile'=>false,
)); ?>

スキン機能はテーマの使用を必要としない、ということに注意してください。 しかしながら、テーマがアクティブなときは、Yii はテーマのビューディレクトリの下の skins ディレクトリ (例えば、WebRoot/themes/classic/views/skins) からもスキンを見つけようとします。 テーマのビューディレクトリにも、メインのアプリケーションビューディレクトリにも同じ名前のスキンが存在する場合は、テーマのスキンが優先されます。

ウィジェットが存在しないスキンを使おうとしている場合でも、Yii はいつも通り、何のエラーもなく、ウィジェットを生成します。

情報: スキンを使用するとパフォーマンスの低下を招くことがあります。 ウィジェットが最初に生成されるときに、Yii がスキンファイルを探す必要があるためです。

スキンはグローバルなウィジェットカスタマイズ機能と非常によく似ています。 主な違いは次の各点です。

  • スキンは表示に関するプロパティ値のカスタマイズに関係が深い
  • ウィジェットは複数のスキンを持つことが出来る
  • スキンに対してはテーマの適用が可能である
  • スキンの使用はグローバルなウィジェットカスタマイズの使用に比べて、コストが高く付く
$Id$

Be the first person to leave a comment

Please to leave your comment.