- Getting Started
- Initial Prototyping
- Post Management
- Comment Management
- Portlets
- Final Work
Tag cloud displays a list of post tags with visual decorations hinting the popularity of each individual tag.
TagCloud ClassWe create the TagCloud class in the file /wwwroot/blog/protected/components/TagCloud.php. The file has the following content:
Yii::import('zii.widgets.CPortlet'); class TagCloud extends CPortlet { public $title='Tags'; public $maxTags=20; protected function renderContent() { $tags=Tag::model()->findTagWeights($this->maxTags); foreach($tags as $tag=>$weight) { $link=CHtml::link(CHtml::encode($tag), array('post/index','tag'=>$tag)); echo CHtml::tag('span', array( 'class'=>'tag', 'style'=>"font-size:{$weight}pt", ), $link)."\n"; } } }
Unlike the UserMenu portlet, the TagCloud portlet does not use a view. Instead, its presentation is done in the renderContent() method. This is because the presentation does not contain much HTML tags.
We display each tag as a hyperlink to the post index page with the corresponding tag parameter. The font size of each tag link is adjusted according to their relative weight among other tags. If a tag has higher frequency value than the other, it will have a bigger font size.
TagCloud PortletUsage of the TagCloud portlet is very simple. We modify the layout file /wwwroot/blog/protected/views/layouts/column2.php as follows,
...... <div id="sidebar"> <?php if(!Yii::app()->user->isGuest) $this->widget('UserMenu'); <?php $this->widget('TagCloud', array( 'maxTags'=>Yii::app()->params['tagCloudCount'], )); </div> ......
Should the code in the view be :
<?php foreach($this->getTagWeights() as $tag=>$weight): ?>
rather than :
<?php foreach(Tag::model()->findTagWeights() as $tag=>$weight): ?>
since using the Model in the view kind of 'breaks' MVC philosophy
or dos it matter at all ?
thanks
A View should be a visual READ_ONLY representation of a Model's data (state).
Rules in MVC says, it's normal to use models in views. In this case, we call it "pull model", where view is responsible for calling the model when it needs. Therefore, nothing is broken and it's perfectly okay, but you will break the rule if you change the state of the model.
So remember: the view only queries the model for state information, but NEVER CHANGES the model's state!
Very simple ;)
I could not find the function getTagWeigths so I wrote one:
public function findTagWeights($maxTags=20)
{
$criteria = new CDbCriteria();
$criteria->limit = $maxTags;
$tags = Tag::model()->findAll($criteria);
$tagWeigths = array();
foreach($tags as $tag)
{
$weigth = $tag->frequency+8;
$weigth = $weigth>=12 ? 12 : $weigth;
$tagWeigths[$tag->name] = $weigth;
}
return $tagWeigths;
}
Hope this helps.
You need to modify your config/main.php and add a row under 'params' which is
'tagCloudCount'=>20.
hello
can not seem to understand what the use of getTagWeights method in TagCloud is
in the widget view there is a direct call to the findTagWeights model method
how would I go about calling the Widget (controller part) method in its view ?
thanks