Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

* Added support for using widget skins.

  • Loading branch information...
commit e866bcb07f7838f5db1451af4b2f9a739de6b22a 1 parent 768d676
qiang.xue authored
View
1  CHANGELOG
@@ -8,6 +8,7 @@ Version 1.1a to be released
- New: Added CDbSchema::checkIntegrity() and resetSequence() (Qiang)
- New: Added phpunit-based testing framework (Qiang)
- New: Added CForm and relevant classes to allow reusing form representation and rendering (Qiang)
+- New: Added support for widget skins (Qiang)
- Chg #433: Changed application and module parameter names to be case-sensitive (Qiang)
- Chg #556: CHtml::resolveName now supports array-typed properties (pestaa)
- Chg: Changed AR eager loading so that it generates and executes a single SQL statement by default (Qiang)
View
2  docs/guide/changes.txt
@@ -8,6 +8,8 @@ Version 1.1.0
* [Added support for writing unit and functional tests](/doc/guide/test.overview)
+ * [Added support for using widget skins](/doc/guide/topics.theming#skin)
+
* Improved the way of declaring safe model attributes.
* Changed the default eager loading algorithm for relational active record queries so that all tables are joined in one single SQL statement.
View
2  docs/guide/toc.txt
@@ -54,7 +54,7 @@
* Special Topics
- [URL Management](topics.url)
- [Authentication and Authorization](topics.auth)
- - [Theming](topics.theming)
+ - [Theming and Skin](topics.theming)
- [Logging](topics.logging)
- [Error Handling](topics.error)
- [Web Service](topics.webservice)
View
64 docs/guide/topics.theming.txt
@@ -62,4 +62,68 @@ Otherwise, it falls back to the default location as specified by
> ~~~
>
+Skin
+----
+
+> Note: The skin feature has been available since version 1.1.0.
+
+While using a theme we can quickly change the outlook of views, we can use skins to systematically customize the outlook of the [widgets](/doc/guide/basics.view#widget) used in the views.
+
+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 [CLinkPager] widget and the skin is named as `classic`.
+
+In order to use the skin feature, we first need to modify the application configuration by enabling the `widgetFactory` component:
+
+~~~
+[php]
+return array(
+ 'components'=>array(
+ 'widgetFactory'=>array(
+ 'enabled'=>true,
+ ),
+ ),
+);
+~~~
+
+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,
+
+~~~
+[php]
+<?php
+return array(
+ 'default'=>array(
+ 'nextPageLabel'=>'&gt;&gt;',
+ 'prevPageLabel'=>'&lt;&lt;',
+ ),
+ 'classic'=>array(
+ 'header'=>'',
+ 'maxButtonCount'=>5,
+ ),
+);
+~~~
+
+In the above, we create two skins for the [CLinkPager] 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 [CLinkPager] widget whose `skin` property is specified as `classic`. For example, the following view code will use the `classic` skin for the pager:
+
+~~~
+[php]
+<?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.
+
+~~~
+[php]
+<?php $this->widget('CLinkPager', array(
+ 'skin'=>'classic',
+ 'maxButtonCount'=>6,
+ 'cssFile'=>false,
+)); ?>
+~~~
+
+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.
+
+> Info: Using skin may degrade the performance because Yii needs to look for the skin file the first time a widget is being created.
+
+
<div class="revision">$Id$</div>
View
24 framework/web/CWidgetFactory.php
@@ -32,7 +32,7 @@
* It is thus represented as an associative array of name-value pairs.
* Skins are stored in PHP scripts like other configurations. Each script file stores the skins
* for a particular widget type and is named as the wiget class name (e.g. CLinkPager.php).
- * Each widget type may have one or several skins, identified by the skin ID set via
+ * Each widget type may have one or several skins, identified by the skin name set via
* {@link CWidget::skin} property. If the {@link CWidget::skin} property is not set for a given
* widget, it means the default skin would be used. The following shows the possible skins for
* the {@link CLinkPager} widget:
@@ -57,7 +57,8 @@
* By default, CWidgetFactory looks for the skin of a widget under the "skins" directory
* of the current application's {@link CWebApplication::viewPath} (e.g. protected/views/skins).
* If a theme is being used, it will look for the skin under the "skins" directory of
- * the theme's {@link CTheme::viewPath}. In case the specified skin is not found, a widget will still be created
+ * the theme's {@link CTheme::viewPath} (as well as the aforementioned skin directory).
+ * In case the specified skin is not found, a widget will still be created
* normally without causing any error.
*
* Note that by default, the "widgetFactory" component is not enabled. It may be enabled
@@ -95,9 +96,7 @@ public function init()
{
parent::init();
- if(($theme=Yii::app()->getTheme())!==null)
- $this->skinPath=$theme->getSkinPath();
- else if($this->skinPath===null)
+ if($this->skinPath===null)
$this->skinPath=Yii::app()->getViewPath().DIRECTORY_SEPARATOR.'skins';
}
@@ -113,10 +112,11 @@ public function createWidget($owner,$className,$properties=array())
$className=Yii::import($className,true);
$widget=new $className($this);
$skinName=isset($properties['skin']) ? $properties['skin'] : 'default';
- if(($skin=$this->getSkin($className,$skinName))!==array())
+ if($skinName!==false && ($skin=$this->getSkin($className,$skinName))!==array())
$properties=$properties===array() ? $skin : CMap::mergeArray($skin,$properties);
foreach($properties as $name=>$value)
$widget->$name=$value;
+ return $widget;
}
/**
@@ -134,6 +134,18 @@ protected function getSkin($className,$skinName)
$this->_skins[$className]=require($skinFile);
else
$this->_skins[$className]=array();
+
+ if(($theme=Yii::app()->getTheme())!==null)
+ {
+ $skinFile=$theme->getSkinPath().DIRECTORY_SEPARATOR.$className.'.php';
+ if(is_file($skinFile))
+ {
+ $skins=require($skinFile);
+ foreach($skins as $name=>$skin)
+ $this->_skins[$className][$name]=$skin;
+ }
+ }
+
if(!isset($this->_skins[$className][$skinName]))
$this->_skins[$className][$skinName]=array();
}
View
3  framework/web/widgets/CWidget.php
@@ -34,7 +34,8 @@ class CWidget extends CBaseController
*/
public $actionPrefix;
/**
- * @var string the name of the skin to be used by this widget. Defaults to 'default'.
+ * @var mixed the name of the skin to be used by this widget. Defaults to 'default'.
+ * If this is set as false, no skin will be applied to this widget.
* @see CWidgetFactory
* @since 1.1
*/
Please sign in to comment.
Something went wrong with that request. Please try again.