主題

主題是一個在 Web 應用程式裡制定網頁外觀的系統方式。通過採用一個新的主題,網頁應用程式的整體外觀可以及時和戲劇性的改變。

在 Yii,每個主題由一個目錄代表,包含視圖檔案,佈局檔案和相關的資源檔案,如圖片, CSS檔案,JavaScript 檔案等。主題的名字就是他的目錄名字。全部主題都放在在同一目錄 WebRoot/themes 下 。在任何時候,只有一個主題可以被啟動。

提示:預設的主題根目錄 WebRoot/themes 可被配置成其他的。只需要配置 themeManager 應用程式元件的屬性 basePathbaseUrl 為你所要的值。

要啟動一個主題,設置 Web 應用程式的屬性 theme 為你所要的名字。可以在 application configuration中配置或者在執行過程中在控制器的動作裡面修改。

註:主題名稱是區分大小寫的。如果您嘗試啟動一個不存在的主題,yii: :app()->theme 將返回 null

主題目錄裡面內容的組織方式和 application base path目錄下的組織方式一樣。例如,所有的視圖檔案必須位於 views 下 ,佈局視圖檔案在 views/layouts 下 ,系統視圖檔案在 views/system 下。例如,如果我們要替換 PostControllercreate 視圖檔案為 classic 主題,我們將儲存新的視圖檔案為 WebRoot/themes/classic/views/post/create.php

對於在 module 裡面的控制器視圖檔案,相應主題視圖檔案將被放在 views 目錄下。例如,如果上述的 PostController 是在一個名為 forum 的模組裡 ,我們應該儲存create 視圖 檔案為 WebRoot/themes/classic/views/forum/post/create.php。如果 forum 模組巢狀在另一個名為 support 模組裡 ,那麼視圖檔案應為 WebRoot/themes/classic/views/support/forum/post/create.php

註:由於 views 目錄可能包含安全敏感資料,應當配置以防止被網絡使用者存取。

當我們調用 renderrenderPartial顯示視圖,相應的視圖檔案以及佈局檔案將在當前啟動的主題裡尋找。如果發現,這些檔案將被呈現。否則,就後退到 viewPathlayoutPath 所指定的預設位置尋找。

baseurl 屬性,我們就可以為此圖像檔案產生如下 url,
yii">

提示:在一個主題的視圖,我們經常需要鏈接其他主題資源檔案。例如,我們可能要顯示一個在主題下 images 目錄裡的圖像檔案。使用當前啟動主題的 baseurl 屬性,我們就可以為此圖像檔案產生如下 Url,

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

下面的範例是一個擁有兩個主題的應用程式的目錄結構。

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 目錄來尋找。

主題小工具

版本 1.1.5 後,小工具的視圖也可以主題化。特別是,當我們調用 CWidget::render() 來呈現小工具視圖,Yii 會嘗試搜尋在主題目錄下尋找小工具的視圖檔案。

想把一個 Foo 小工具的視圖 xyz 主題化,我們應該先建立一個目錄叫做 Foo(跟小工具同) 在當前啟動的主題視圖目錄。如果一個小工具置於命名空間裡(PHP 5.3.0 以上),像是 \app\widgets\Foo,我們應建議一個叫做 app_widgets_Foo 的目錄。就是,我們用底線置換了命名空間的分隔符號。

接下來建立一個視圖檔案叫做 xyz.php 在新建立的目錄下。最後,我們應該就會有一個檔案 themes/basic/views/Foo/xyz.php,將會被小工具用來置換原本的視圖,如果當前的主題是 basic

全域地客製化小工具

注意: 這功能版本 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 屬性來指定全域小工具客製化給 CLinkPagerCJuiDatePicker。需要注意的是每個小工具的全域客製化是儲存成鍵-值配對的陣列,鍵代表小工具類別的名稱,而值則是屬性的初始化陣列值。

現在,不論何時我們要建立一個 CLinkPager 小工具在一個視圖,上述屬性會被賦予給小工具,然後我們只需要如下的方式來建立這個小工具:

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

如果需要,我們也可以覆蓋初始化的屬性值。例如,如果某些視圖我們想要設定 maxButtonCount 成為 2,我們可以:

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

外表

注意: 外表功能從版本 1.1.0 開始支援。

當使用一個主題時,我們可以快速的改變一個視圖的外關,我們可以使用外表來有系統地客製化視圖裡使用的 widgets 的外觀。

一個外表是一個名稱-值配對的陣列,可以被用來初始化小工具的屬性。一個外表屬於一個小工具類別,一個小工具還可以藉由不同的外表名稱還擁有許多外表。例如,我們可以有一個小工具 CLinkPager 的外表而且名稱是 classic

為了使用外表功能,首先必須修改應用程式的配置,設定 CWidgetFactory::enableSkin 屬性為 true 給 widgetFactory 應用程式元件:

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

請注意,在版本 1.1.3 之前,你必須用下述的配置來開啟小工具外表功能:

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

然後,就建立我們需要的外表。一個儲存在 PHP 腳本檔案的外表屬於那些具有相同名稱的一個小工具類別。預設上,這些外表檔案被放置在 protected/views/skins 下。如果你想要放在不同的資料夾下,你可以設定 widgetFactory 元件的屬性 skinPath 。例如,我們可以在 protected/views/skins 建立一個名叫 CLinkPager.php 檔案,內容如下,

<?php
return array(
    'default'=>array(
        'nextPageLabel'=>'&gt;&gt;',
        'prevPageLabel'=>'&lt;&lt;',
    ),
    'classic'=>array(
        'header'=>'',
        'maxButtonCount'=>5,
    ),
);

上述,我們建立了兩個外表給 CLinkPager 小工具: defaultclassic。前者是給任何 CLinkPager 小工具使用的外表,我們沒有清楚地指定他的 skin 屬性,而後者是給指定成 classicCLinkPager 小工具使用的外表。例如,下述的視圖程式碼,第一個頁碼器會使用 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$