mem
(Talofo)
May 17, 2012, 3:35pm
1
Hello all,
Partials will be a view with no layout attached, for small non complex logic involved.
Layouts will be for common elements, header footer, column1, 3columns…
Widgets will be for elements that have a complex logic behind like calendars, galleries, and navigation menus (like cmenu widget);
Clips
This was all that I can read on Yii guide about it.
Calendar and Galleries sure are
. Hence, the trouble:
On what circumstances should we use clips ?
Thanks in advance.
yiwi
(Kdietrich9000)
May 17, 2012, 5:10pm
2
Haha, up to now I haven’t heard of clips at all, but why don’t you try the forum search?
I found an application example here: http://www.yiiframework.com/forum/index.php/topic/1780-example-on-using-clips/
mem
(Talofo)
May 20, 2012, 6:52pm
3
I see nothing there. No example of using clips at all. And, above all, any explanation about on what circumstances should we use or not clips.
Y11
(Y!!)
May 20, 2012, 7:10pm
4
Imagine you have clientside-sortable portlets. With clips you can first record all the portlets in a default order. Then you can display them based on the order defined by the user. Simple example:
// record each portlet here in any order
...
$_COOKIE['portlet-order'] = 'login|poll|something-else'; // this order was set by the client
$portlets = explode('|', $_COOKIE['portlet-order']);
foreach (portlets as $portlet)
{
echo $this->clips[$portlet];
}
mem
(Talofo)
May 20, 2012, 7:22pm
5
Thanks.
Still not getting. Sorry. English is not my main language, and that could play a role here. As a plus, I don’t consider myself a great programmer so, that’s also an issue. All this to say: “Please have patience”
So:
Imagine you have clientside-sortable portlets. With clips you can first record all the portlets in a default order. Then you can display them based on the order defined by the user. Simple example:
// record each portlet here in any order
...
$_COOKIE['portlet-order'] = 'login|poll|something-else'; // this order was set by the client
$portlets = explode('|', $_COOKIE['portlet-order']);
foreach (portlets as $portlet)
{
echo $this->clips[$portlet];
}
So, portlet can be clips? So, for example, the "Poll" would be a clip ?
But the pull has a lot of logic involved. Shouldn’t that be a Widget ?
Or a clip could be a widget ?
Y11
(Y!!)
May 20, 2012, 7:30pm
6
$this->beginClip('login');
$this->widget('LoginWidget');
$this->endClip();
$this->beginClip('poll');
$this->widget('PollWidget');
$this->endClip();
$portlets = explode('|', $_COOKIE['portlet-order']);
foreach (portlets as $portlet)
{
echo $this->clips[$portlet];
}
So with clips you can record different fragments of a page and then display them dynamically.
thefsb
(Fsb)
May 20, 2012, 8:57pm
7
$this->beginClip('login');
$this->widget('LoginWidget');
$this->endClip();
$this->beginClip('poll');
$this->widget('PollWidget');
$this->endClip();
$portlets = explode('|', $_COOKIE['portlet-order']);
foreach (portlets as $portlet)
{
echo $this->clips[$portlet];
}
So with clips you can record different fragments of a page and then display them dynamically.
I’m not sure I get it yet. The above could be accomplished more easily using the $captureOutput argument of CController::widget.
A key difference it seems is that you can record arbitrary output between the beginClip and endClip.
$this->beginClip('login');
$this->widget('LoginWidget');
echo 'Some string';
$this->renderPartial('aView');
echo 'etc...';
$this->endClip();
and you can capture any number of them.
I should have phrased this as a question. I’ve never used clips.
Plus cant we just do that with partials anyway?
jacmoe
(Jacob Moena)
May 20, 2012, 10:10pm
9
Yeah, but you can run clips in any controller - anywhere.
I use it from time to time.
Instead of passing arrays to sidebars and other elements, it’s much simpler to use a clip or two. And it’s cleaner as well.
jacmoe
(Jacob Moena)
May 20, 2012, 10:14pm
10
For example, I have this in components/controller.php:
class Controller extends CController {
public $sidebar_content = '';
public $users_online = null;
public $visitorTableName = '{{visitor}}';
protected function beforeAction($action) {
if (isset(Yii::app()->user->id)) {
$user_id = Yii::app()->user->id;
//TODO: Don't do this every time the app runs??
$sql = "SELECT user_id FROM {$this->visitorTableName} WHERE user_id=:user_id";
if (Yii::app()->db->createCommand($sql)->bindValue(':user_id', $user_id)->queryScalar() === false)
$sql = "INSERT INTO {$this->visitorTableName} (user_id, last_activity) VALUES (:user_id, :last_activity)";
else
$sql = "UPDATE {$this->visitorTableName} SET last_activity=:last_activity WHERE user_id=:user_id";
Yii::app()->db->createCommand($sql)->bindValue(':user_id', $user_id)->bindValue(':last_activity', date('Y-m-d H:i:s'))->execute();
}
$users = Yii::app()->db->createCommand()
->select('u.id, username, TIMESTAMPDIFF(MINUTE, last_activity, UTC_TIMESTAMP())')
->from('{{usergroups_user}} u')
->join("{$this->visitorTableName} v", 'u.id=v.user_id')
->where('TIMESTAMPDIFF(MINUTE, last_activity, UTC_TIMESTAMP()) < 5')
->queryAll();
$this->users_online = $users;
$this->beginWidget('system.web.widgets.CClipWidget', array('id' => 'users_online'));
if (isset($this->users_online)) {
foreach ($this->users_online as $user)
if (isset($user)) {
echo '<b>' . ucfirst($user['username']) . '</b> <small>(';
echo 'Idle for ' . $user['TIMESTAMPDIFF(MINUTE, last_activity, UTC_TIMESTAMP())'] . ' minutes)</small><br/>';
}
} else {
echo 'none';
}
$this->endWidget();
$this->beginWidget('system.web.widgets.CClipWidget', array('id' => 'site_statistics'));
echo CHtml::openTag('p');
echo 'online: ' . Yii::app()->usercounter->getOnline() . '<br />';
echo 'today: ' . Yii::app()->usercounter->getToday() . '<br />';
echo 'yesterday: ' . Yii::app()->usercounter->getYesterday() . '<br />';
echo 'total: ' . Yii::app()->usercounter->getTotal() . '<br />';
echo 'maximum: ' . Yii::app()->usercounter->getMaximal() . '<br />';
echo 'date for maximum: ' . date("Y-m-d H:i:s", Yii::app()->usercounter->getMaximalTime()) . '<br />';
echo CHtml::closeTag('p');
$this->endWidget();
return true;
}
Maybe not a prime example of good coding practices, but at least it makes it possible to use those two clips anywhere.
Without cluttering up controllers/views.
yiqing95
(Yiqing 95)
May 22, 2012, 10:45am
11
you can also use clips to pass content to layouts from view file ;
clulumn2 :
if(isset($this->clips['someSpecMenu'])){
echo $this->clips['someSpecMenu'];
}
in your action or view file:
$this->beginClip('someSpecMenu');
// echo any content here ;
$this->endClip();
thus different controller can use a same layout file (column2) but in some area it can output different contents (menus , widgets , ad … and so no )
Haensel
(Johannes)
May 22, 2012, 1:29pm
12
@jacmoe , yiqing95, Y!!: Thanks for the info. I have to admit I never got the use of clips but they actually seem more flexible than partials or public controller attributes.
EDIT: Just tested it, so much better than the lame use of public properties
mem
(Talofo)
May 22, 2012, 2:57pm
13
Sure the examples will help me out to do similar things when I found myself on the same or near circumstances. I still believe it would be helpful if we have, on a manual, some theoretical references about this, well organized that we can read and truly comprehend.
Thank you all for all your comments and examples provided that have helped.
Cheers,
mem
Don_Khan
(Don Khan)
April 16, 2014, 3:59pm
14
I’ve just gotten past a bit of the learning curve with clips, so I thought I’d share my current solution.
Basically, I wanted a re-useable CMenu sidebar widget for various departments of my site.
My controller looks like this (I’m using actions too):
class ExampleController extends Controller
{
...
public function actions()
{
return array(...
'stories' => array(
'class' => 'application.controllers.example.StoriesAction',
),
);
}
}
Then, my StoriesAction (controllers/example/StoriesAction.php) looks like this.
class StoriesAction extends CAction
{
public function run()
{
...
$this->controller->renderPartial("_sidebar");
$this->controller->layout = 'sidebarleft';
$this->controller->render("stories");
}
}
Then, in views/example/_sidebar.php:
$this->beginClip('sidebar');
$this->widget('zii.widgets.CMenu', array(
'activeCssClass'=>'active',
'itemCssClass' => 'item',
...
));
$this->endClip();
The sidebarleft layout contains, among other things:
<?php echo $this->clips['sidebar']; ?>
<?php echo $content; ?>
This way, each controller can have its own sidebar, written as a single script, which is rendered into a clip and used in a global layout. Niiice.
jkofsky
(Jkofsky)
April 16, 2014, 6:02pm
15
mem:
Hello all,
Partials will be a view with no layout attached, for small non complex logic involved.
Layouts will be for common elements, header footer, column1, 3columns…
Widgets will be for elements that have a complex logic behind like calendars, galleries, and navigation menus (like cmenu widget);
Clips
This was all that I can read on Yii guide about it.
Calendar and Galleries sure are
. Hence, the trouble:
On what circumstances should we use clips ?
Thanks in advance.
One of the primary uses of clips, if my research is right, is server optimization. If you have a db query that takes a while to complete, you could save the result in a clip. Then when you run the query the first time it takes how eve long to complete, but for the next request the server just sends the clip. I believe there is a way, either programmer if() test or clip expire thing, to get fresh clip if underlying data changes.
Just my 2 cents