[FYI: I posted my proposed mods to the Yii source in the first response to this post.]
For Javascript and CSS that pertains to only one view file, I want to put that Javascript and CSS in the view file, and I’d like the layout to render this in the head tag.
I’ve discovered controller clips via the CClipWidget. This allows conveying HTML to the layout, but it doesn’t seem to allow for accumulating HTML for the layout. I need to accumulate so that partials can each provide their own Javascript and CSS, in addition to allowing their including views to provide Javascript and CSS. That way my HTML head tag can include all the bits needed by each of the views in a generic way, without having to code for knowledge of all the partials.
I don’t see an existing mechanism for accomplishing this application-wide. I’m thinking that it could be done via an “appendClip()” method on the controller, complementing the existing “beginClip()”. For now I’ve concocted a hack that accomplishes this by first having the view stage the clip-to-append to a temporary ‘clipboard’ clip. It’s messier than I would like.
Here’s my interim “appendClipboard()” helper method:
/**
* appendClipboard() appends the clip named 'clipboard' to the clip of
* the provided name, creating that clip if it doesn't already exist.
*
* @param object $controller View's controller
* @param string $targetClip Name of clip to which to append clipboard
*/
public static function appendClipboard($controller, $targetClip)
{
$oldClip = '';
if(isset($controller->clips[$targetClip]))
$oldClip = $controller->clips[$targetClip];
$controller->beginClip($targetClip);
echo $oldClip;
echo $controller->clips['clipboard'];
$controller->endClip($targetClip);
}
Here’s how I use this interim method:
views/layouts/main.php:
<head>
...
<?php if(isset($this->clips['head_code']))
echo $this->clips['head_code']; ?>
</head>
views/mymodel/create.php:
<?php $this->beginClip('clipboard'); ?>
<!--Head code from create.php-->
<?php $this->endClip('clipboard'); ?>
<?php JoesHtml::appendClipboard($this, 'head_code'); ?>
views/mymodel/_form.php:
<?php $this->beginClip('clipboard'); ?>
<!--Head code from _form.php-->
<?php $this->endClip('clipboard'); ?>
<?php JoesHtml::appendClipboard($this, 'head_code'); ?>
Resulting rendering:
<head>
...
<!--Head code from create.php-->
<!--Head code from _form.php-->
</head>
Ideally, Yii would allow me to simply call appendClip() in place of beginClip() to accomplish this, without requiring the above appendClipboard() hack. I’m guessing that this would require a special CAppendingClipWidget, constructed within appendClip().