Theming(主题)

    在Yii,每个主题由一个目录代表,包含view文件,layout文件和相关的资源文件,如图片, CSS文件, JavaScript文件等。主题的名字就是他的目录名字。全部主题都放在在同一目录下 。在任何时候,只有一个主题可以被激活。

    要激活一个主题,设置Web应用程序的属性为你所要的名字。可以在application configuration中配置或者在执行过程中在控制器的动作里面修改。

    注:主题名称是区分大小写的。如果您尝试启动一个不存在的主题, yii: :app()->theme将返回null

    主题目录里面内容的组织方式和目录下的组织方式一样。例如,所有的view文件必须位于views下 ,布局view文件在views/layouts下 ,和系统view文件在views/system下。例如,如果我们要替换PostControllercreate view文件为classic主题下,我们将保存新的view文件为WebRoot/themes/classic/views/post/create.php

    对于在module里面的控制器view文件,相应主题view文件将被放在views目录下。例如,如果上述的PostController是在一个命名为forum的模块里 ,我们应该保存create view 文件为WebRoot/themes/classic/views/forum/post/create.php 。如果 forum模块嵌套在另一个名为模块里 ,那么view文件应为WebRoot/themes/classic/views/support/forum/post/create.php

    当我们调用或renderPartial显示视图,相应的view文件以及布局文件将在当前激活的主题里寻找。如果发现,这些文件将被render渲染。否则,就后退到和layoutPath 所指定的预设位置寻找。

    baseurl属性,我们就可以为此图像文件生成如下url,

    Below is an example of directory organization for an application with two themes basic and fancy.

    1. WebRoot/
    2. assets
    3. protected/
    4. .htaccess
    5. components/
    6. controllers/
    7. models/
    8. views/
    9. layouts/
    10. main.php
    11. site/
    12. index.php
    13. themes/
    14. basic/
    15. views/
    16. .htaccess
    17. layouts/
    18. main.php
    19. site/
    20. index.php
    21. fancy/
    22. .htaccess
    23. layouts/
    24. main.php
    25. site/
    26. index.php

    In the application configuration, if we configure

    1. return array(
    2. 'theme'=>'basic',
    3. ......
    4. );

    then the basic theme will be in effect, which means the application's layout will usethe one under the directory themes/basic/views/layouts, and the site's index view willuse the one under themes/basic/views/site. In case a view file is not found in the theme,it will fall back to the one under the protected/views directory.

    To theme the view xyz for a widget whose class name is Foo, we should first create a folder named Foo (same as the widget class name) under the currently active theme's view folder. If the widget class is namespaced (available in PHP 5.3.0 or above), such as \app\widgets\Foo, we should create a folder named app_widgets_Foo. That is, we replace the namespace separators with the underscore characters.

    We then create a view file named xyz.php under the newly created folder. To this end, we should have a file themes/basic/views/Foo/xyz.php, which will be used by the widget to replace its original view, if the currently active theme is basic.

    When using a widget provided by third party or Yii, we often need to customizeit for specific needs. For example, we may want to change the value of from 10 (default) to 5. We can accomplish thisby passing the initial property values when calling CBaseController::widgetto create a widget. However, it becomes troublesome to do so if we have torepeat the same customization in every place we use .

    Using the global widget customization feature, we only need to specify theseinitial values in a single place, i.e., the application configuration. Thismakes the customization of widgets more manageable.

    To use the global widget customization feature, we need to configure thewidgetFactory as follows:

    1. return array(
    2. 'components'=>array(
    3. 'widgetFactory'=>array(
    4. 'widgets'=>array(
    5. 'CLinkPager'=>array(
    6. 'maxButtonCount'=>5,
    7. 'cssFile'=>false,
    8. ),
    9. 'CJuiDatePicker'=>array(
    10. 'language'=>'ru',
    11. ),
    12. ),
    13. ),
    14. ),
    15. );

    In the above, we specify the global widget customization for both and CJuiDatePicker widgets by configuring the property. Note that the global customization for each widget is representedas a key-value pair in the array, where the key refers to the wiget classname while the value specifies the initial property value array.

    Now, whenever we create a CLinkPager widget in a view, the above propertyvalues will be assigned to the widget, and we only need to write the followingcode in the view to create the widget:

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

    We can still override the initial property values when necessary. For example,if in some view we want to set maxButtonCount to be 2, we can do the following:

    1. 'pages'=>$pagination,
    2. 'maxButtonCount'=>2,
    3. ));
    Note: The skin feature has been available since version 1.1.0.

    A skin is an array of name-value pairs that can be used to initialize the properties of a widget. A skin belongs to a widget class, and a widget class can have multiple skins identified by their names. For example, we can have a skin for the widget and the skin is named as .

    In order to use the skin feature, we first need to modify the application configuration by configuring the CWidgetFactory::enableSkin property to be true for the widgetFactory application component:

    Please note that in versions prior to 1.1.3, you need to use the following configuration to enable widget skinning:

    1. return array(
    2. 'components'=>array(
    3. 'widgetFactory'=>array(
    4. 'class'=>'CWidgetFactory',
    5. ),
    6. ),
    7. );

    We then create the needed skins. Skins belonging to the same widget class are stored in a single PHP script file whose name is the widget class name. All these skin files are stored under protected/views/skins, by default. If you want to change this to be a different directory, you may configure the skinPath property of the widgetFactory component. As an example, we may create under protected/views/skins a file named CLinkPager.php whose content is as follows,

    1. <?php
    2. return array(
    3. 'default'=>array(
    4. 'nextPageLabel'=>'&gt;&gt;',
    5. 'prevPageLabel'=>'&lt;&lt;',
    6. ),
    7. 'classic'=>array(
    8. 'header'=>'',
    9. 'maxButtonCount'=>5,
    10. ),
    11. );

    In the above, we create two skins for the widget: default and classic. The former is the skin that will be applied to any CLinkPager widget that we do not explicitly specify its skin property, while the latter is the skin to be applied to a widget whose skin property is specified as classic. For example, in the following view code, the first pager will use the default skin while the second the classic skin:

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

    If we create a widget with a set of initial property values, they will take precedence and be merged with any applicable skin. For example, the following view code will create a pager whose initial values will be array('header'=>'', 'maxButtonCount'=>6, 'cssFile'=>false), which is the result of merging the initial property values specified in the view and the classic skin.

    Note that the skin feature does NOT require using themes. However, when a theme is active, Yii will also look for skins under the skins directory of the theme's view directory (e.g. WebRoot/themes/classic/views/skins). In case a skin with the same name exists in both the theme and the main application view directories, the theme skin will take precedence.

    If a widget is using a skin that does not exist, Yii will still create the widget as usual without any error.

    • Skin is more related with the customization of presentational property values;
    • A widget can have multiple skins;
    • Skin is themeable;

    原文: https://www.yiiframework.com/doc/guide/1.1/zh-cn/topics.theming