Customizing Yii's formatting rules (extending CFormatter)

You are viewing revision #1 of this wiki article.
This is the latest version of this article.

CFormatter is one of Yii's core components and used to format values displayed in widgets like CGridView or CDetailView. All classic formats like numbers, text, urls or datetime are supported but you may have to use a formatting rule that isn't built in. Let's say we want to display arrays of strings (like tags associated with a product model). When using CDetailView we would usually make use of PHPs implode function to create a simple string value of all values in the $product->tags array.

$this->widget('zii.widgets.CDetailView', array(
    'data'=>$product,
    'attributes'=>array(
        'title',             
        array(               
            'label'=>'Tags',
            'type'=>'text',
            'value'=>implode(', ',$product->tags),
        ),
    ),
));

This is one way of doing it but to show you how easy it is to use customized formatting rules we will extend CFormatter and add a new function called formatArray($value) that will allow us to specify a new format type called 'array'.

First create a class called MyFormatter

class MyFormatter extends CFormatter
{
	public $implodeSign=', ';

	public function formatArray($value)
	{
		if(is_array($value))
			return implode($this->implodeSign,$value)
	}
}

Two things are important here:

  1. Yii will always search for a function called formatTHETYPEYOUSPECIFIED. So when using 'type'=>'url' it will search for a function called formatUrl($value) and pass the value to this function.

  2. The $value parameter is the value you specified in your widget (in our case the $product->tags array)

Save this file in your extensions folder. Now you will have to tell Yii that it has to use your custom Formatter class.

Put this in your main.php config file:

'components'=>array(
                'format'=>array(
                        'class'=>'application.extensions.MyFormatter'
                ),
)

Now you can specify 'array' as a new format in CDetailView

$this->widget('zii.widgets.CDetailView', array(
    'data'=>$product,
    'attributes'=>array(
        'title',             
        array(               
            'label'=>'Tags',
            'type'=>'array',
            'value'=>$product->tags,
        ),
    ),
));

If you want to change the implode sign from ', ' to ' - ' simply define it in your main.php config

'components'=>array(
                'format'=>array(
                        'class'=>'application.extensions.MyFormatter'
			'implodeSign'=>' - ',
                ),
)

This is one example but you are able to do a lot of additional formatting with a customized Formatter and keep your code clean and organized at the same time.