JQuery-UI theming

Hi!

I’ve read the wiki article “Theming your Zii Widgets” and was a little bit disappointed that one has to configure each [font=“Courier New”]CJuiWidget[/font] individually. Why not configuring the base class instead? But than I saw that the [font=“Courier New”]CWidgetFactory[/font] only sets the properties of the concrete class and not also that of the ancestors.

Therefore I changed [font="Courier New"]CWidgetFactory[/font] to contain a new private method:




	/*

	 * Merge all properties of parent classes first and than the properties of

	 * the more specific classes

	 */

	private function mergeProperties($className, $properties)

	{

		$parent = get_parent_class($className);

		// Resolve up to CWidget

		if (is_subclass_of($parent, 'CWidget') || $parent == 'CWidget')

		{

			$properties = $this->mergeProperties($parent, $properties);

		}

		if(isset($this->widgets[$className]))

		{

			$properties=$properties===array() ? 

				$this->widgets[$className] : CMap::mergeArray($this->widgets[$className],$properties);

		}

		return $properties;

		

	}



and then let the method [font="Courier New"]CWidgetFactory->createWidget[/font] call it:




	public function createWidget($owner,$className,$properties=array())

	{

		$className=Yii::import($className,true);

		$widget=new $className($owner);


		$properties = $this->mergeProperties($className, $properties);

		

		if($this->enableSkin)

		{

			if($this->skinnableWidgets===null || in_array($className,$this->skinnableWidgets))

			{

				$skinName=isset($properties['skin']) ? $properties['skin'] : 'default';

				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;

	}



Now it’s as easy as:




        'widgetFactory' => array(

            'widgets' => array(

                'CJuiWidget' => array(

		    'themeUrl' => 'jui/themes',

                    'theme' => 'ghsv',

                ),

	    ),

	),



to add to your components (main.php configuration) to use a different jquery-ui theme in your application, just copy the generated (JQuery’s themeroller) “custom-theme” to an accessible directory (here [font=“Courier New”]jui/themes/ghsv[/font]).

Did I overlook a configuration option, which allows that already or is my idea a valuable enhancement?

Best regards,

Marco

I did something similar here.

Can’t remember the exact reason I didn’t complete the “inheritance approach” (besides performance). It’s probably not meaningful to include CWidget as parent so I settled for an explicit “commonProperties” class (actually just a fake class name in the CWidgetFactory widgets array).

Edit:

Also see this post. Leading to this. Will need some more work for the example below to work.

Example (use skins from "commonProperties" fake class, in this case CJuiWidget).




'widgetFactory' => array(

  'widgets' => array(

    'CJuiWidget' => array(

      'skin'=>'yiitheme',

    ),

  ),

),



I don’t remember if there’s still an unsolved problem. For sure I have commented out the content of


myapp/themes/<selected-yii-theme>/views/skins/CJuiWidget.php

But that might be because I continued testing property inheritance/aggregation of jui widget configurations.

CJuiWidget.php content: Yii theme specific skin(s) for CJuiWidget ancestors




<?php

return array(

  'yiitheme'=>array(

    'themeUrl' => 'jui/themes',

    'theme' => 'ghsv',

    ...

  ),

  ...

);

?>



BTW I never used this in a project and because seemingly no one else found it worth using, I left it in an unfinished state.

/Tommy

Hi Tommy,

stepping up the hierarchy to find ancestor configurations rarely needs more than 1 step, since most widgets directly extend [font="Courier New"]CWidget[/font]. Okay, some widgets take more (at most 3 steps?), when - for example - extending [font="Courier New"]C(Jui)InputWidget[/font] or [font="Courier New"]CFilterWidget[/font]. But this adds also flexibility by enabling configuration just for that classes.

Best regards,

Marco

I think the reason I suggested the "commonProperties" approach, besides the obvious performance hit, also was that the non-Jui widgets have very few, if any, properties in common that would have benefit from the inheritance approach.

/Tommy