You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.
As you know, the CDetailView widget displays details of a single model. If no formatting is specified, boolean values that are stored in the database as 0 and 1, are represented in the detail view as 0 and 1. If formatted as boolean, they are represented as 'No' and 'Yes'. We want to add i18n support, so that Yes and No appear in the current language.
In the following example, 'Logged' is a boolean attribute. You can tell the widget to format the value of that attribute as a boolean so it will be either 'No' or 'Yes', like this:
$this->widget('zii.widgets.CDetailView', array(
'data' => $model,
'attributes' => array(
'ID',
'Logged:boolean',
),
));
In this case, the formatBoolean() method of the class CFormatter will be applied to tha attribute value (see the class reference for details). This essentially replaces 0 with a 'No', and 1 with a 'Yes', which looks much nicer.
To be exact: the class CFormatter has a public property named booleanFormat
which defaults to array('No', 'Yes')
. The formatBoolean()
method replaces a 0 with its first element, and a 1 with its second element.
If the application language is different from english, say german, it would look much nicer if 0 became 'Nein' and 1 became 'Ja'. The first thing that comes to (my) mind is to override the booleanFormat
property in the config file like this:
'components'=>array( //...
'format'=>array(
'booleanFormat'=>array(Yii::t('app','No'), Yii::t('app','Yes')),
), // ...
),
Only, this doesn't work (I guess Yii::t()
cannot be used in the config file). We could override it with array('Nein','Ja')
, which would work, but we don't want to hardcode the german translations here to keep things flexible.
So we extend the CFormatter class. For this we create the file /protected/components/Formatter.php
, override the function formatBoolean()
, and add a new function while we're at it:
class Formatter extends CFormatter {
public function formatBoolean($value){
return $value ? Yii::t('app', $this->booleanFormat[1]) : Yii::t('app',$this->booleanFormat[0]);
}
public function formatHeadline($value) {
return '<b>' . $value . '</b>';
}
}
The new method formatHeadline()
prints the value in bold.
Then we tell Yii to use this class in the config file like this:
'components'=>array( //...
'format'=>array(
'class'=>'application.components.Formatter',
), // ...
),
The value of the 'ID' attribute in the following example will now be displayed in bold letters.
$this->widget('zii.widgets.CDetailView', array(
'data' => $model,
'attributes' => array(
'ID:headline',
'Name',
'Logged:boolean',
),
));
It is that easy to add new and more complicated formatters and simplify your CDetailView calls.
a general way to change the core component class !
@c@cba great works !
here you can see a general method to change the yii's core components to our own class(just extends the subclass of CApplicationComponet includes the some core compoent: request , db etc..). thanks to the ioc tech , the CWebApplication is a components container and a huge object factory , we refer the component instance from it (eg: Yii::app()->someComponetId ; ) thus we can change most components of Yii cores .
How about just extending the array - just for the boolean values?
I just added a __construct() function to wrap the array elements with the translate function. Is this a good practice?
class Formatter extends CFormatter { public function __construct() { $this->booleanFormat=array(Yii::t('app', $this->booleanFormat[0]),Yii::t('app', $this->booleanFormat[1])); } }
Because this allows me to add simple dropdown filters in GridView as well:
... 'filter'=> Yii::app()->format->booleanFormat ...
Yii supports i18n formatting since version 1.14
http://www.yiiframework.com/doc/api/1.1/CLocalizedFormatter
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.