You are viewing revision #6 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.
Introduction ¶
There is a lot of confusion about what happening behind the scene when you render the view.
If we look at blog demo we have 3 major parts of our view randering, and they are:
1) The layouts/column1 and 2, looks like this (column1.php):
<?php $this->beginContent('/layouts/main'); ?>
<div class="container">
<div id="content">
<?php echo $content; ?>
</div><!-- content -->
</div>
<?php $this->endContent(); ?>
2) We have layouts/main
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="language" content="en" />
<!-- blueprint CSS framework -->
<link rel="stylesheet" type="text/css" href="<?php echo Yii::app()->request->baseUrl; ?>/css/screen.css" media="screen, projection" />
<!-- some more headers... -->
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
</head>
<body>
<!-- ... -->
<?php $this->widget('zii.widgets.CBreadcrumbs', array(
'links'=>$this->breadcrumbs,
)); ?><!-- breadcrumbs -->
<?php echo $content; ?>
</body>
</html>
3) and the view that we render , for example site/contact
<?php
$this->pageTitle=Yii::app()->name . ' - Contact Us';
$this->breadcrumbs=array(
'Contact',
);
?>
<h1>Contact Us</h1>
<!-- ... -->
The call to the view rendering in the contact look like this
/**
* Displays the contact page
*/
public function actionContact()
{
$model=new ContactForm;
//some form code was here...
$this->render('contact',array('model'=>$model));
}
![](http://i31.fastpic.ru/big/2011/1007/07/c149a80587fa51c23bd77ed9fa6a3007.jpg "")
The common questions and confusion: ¶
1) why if I pass to the contact some $test variable like $this->render('contact',array('model'=>$model,'test' => 123)); And I echo it in the layout with echo $test, I get error 500 undefind variable error?
2) I dont passed any $content variable so what is
<?php echo $content; ?>
Inside the beginContent tags inside column1.php ?
3) Why the layouts/main.php has
<?php echo $content; ?>
Don't passed such variable...
4) Why both column1.php and main.php echo the $content ?
5) why if I change inside contant.php the title, it changes the main.php $this->title variable ?
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
/* in contact.php $this->pageTitle=Yii::app()->name . ' - Contact Us'; */
And the main confusion: ¶
6) what is called before what? what the heck is going on there ? ;-)
Diving in the source code ¶
You have two options:
1) You can accept the rules and follow them without understanding
2) You can understand and follow the rules...
If you choose number 1, tutorial is over for you ;-) But if you really want to learn and understand, lets dive together...
Every good IDE has the ability to go directly to the function by pressing ctrl and than the function name...So lets go to SiteController.php, to the actionContact and press the render word in this line:
$this->render('contact',array('model'=>$model));
After pressing you will find yourself inside yii/web/CController.php on line 775
public function render($view,$data=null,$return=false)
{
if($this->beforeRender($view))
{
$output=$this->renderPartial($view,$data,true);
if(($layoutFile=$this->getLayoutFile($this->layout))!==false)
$output=$this->renderFile($layoutFile,array('content'=>$output),true);
$this->afterRender($view,$output);
$output=$this->processOutput($output);
if($return)
return $output;
else
echo $output;
}
}
The rendering is starting with a call to beforeRender, This is a preprocessing, if we talking about the blog demo, no preporcessing there, so it is just return true...
protected function beforeRender($view)
{
return true;
}
After we got true, we can continue ...
We have
$output=$this->renderPartial($view,$data,true);
So our 'contact' view is rendered partially, with third parameter as true, this means that the result not echoed to the page, it is captured and passed to the $output variable...
At this stage the contact page is rendered, all the $data it got (the variable array), is passed to the view end was processed
After this, if a layout is defined
if(($layoutFile=$this->getLayoutFile($this->layout))!==false) $output=$this->renderFile($layoutFile,array('content'=>$output),true);
we pass the $output we captured from the contact.php file, and pass it as $content to our layout file column1.php
Also this time the third parameter is true, meaning we done echo the output, we capture it and pass to $output variable (at this point the view output is overwritten, we don't need it any more cause we passed it to the view and it processed).
After this the afterRender called, and the processOutput, it's role is to insert all the javascript css etc. we registered as client scripts etc.
Time for answers ¶
After we followed all the life cycle of the render method, we can answer to all the questions...
1) why if I pass to the contact some $test variable like $this->render('contact',array('model'=>$model,'test' => 123)); And I echo it in the layout with echo $test, I get error 500 undefind variable error?
Answer: Because the parameters we pass to the $this->render method, are processed in the view file , in this example contact.php, and then we pass to the layout the generated view, and the variable $test is out of the scope for hte layout. What to do if you need it? you can use the Yii registry(params), or you can define some class field, or consider creating widget ... (depends on the task)
2) I dont passed any $content variable so what is
<?php echo $content; ?>
Inside the beginContent tags inside column1.php ?
Answer: the captured view is passed to the layout as content parameter
3) Why the layouts/main.php has
<?php echo $content; ?>
Don't passed such variable...
Answer:
<?php
$this->beginContent('//layouts/main');
//...
$this->endContent();
All what between beginContent and endContent, is captured and passed to the layouts/main as content variable...
4) Why both column1.php and main.php echo the $content ?
Answer: If you understood answers to 1-3, you know the answer for this one... they are not the same, and don't have the same value
5) why if I change inside contant.php the title, it changes the main.php $this->title variable ?
<title><?php echo CHtml::encode($this->pageTitle); ?></title>
/* in contact.php $this->pageTitle=Yii::app()->name . ' - Contact Us'; */
Answer:
as we saw, the contact.php is rendered before the layout, so every field( aka class parameters), you change from the view file (contact.php) will effect the layout because it rendered after...
And the main confusion: ¶
6) what is called before what? what the heck is going on there ? ;-)
contact.php (passed as content)-> column1.php (passed as content)-> main.php
That's it, now you pro in layouts ;-) Confession Actually before writing this tutorial I was more in the "rules follower" group ...
Nice
Lol, nice images and graphics. :)
very good
I learned a lot from it. Very good exercise!
Interesting
Interesting images also the tutorial
Good work
I learned a lot from it too. I read this article some times so maybe it is a little help:
After I read this article open this four files and rarely understand the knowledge, but my first question who work is "/protected/views/layouts/column2.php"? So open it:
So if you don't understand first or maybe fifth time, it is little help ...
Great tutorial! Thanks
Feel it's helpful to add a explanation of column1, column2 and main.php.
Essentially the columns are 'extended' layouts which your controller can use.
You can specify the layout per controller like this:
public $layout='//layouts/main;
Helpful diagram
Your blog post helped me understand, but as they say, a picture is worth a thousand words, so here's a diagram.
Great tutorial! Thanks
Great tutorial! Thanks
Great Explaination
Explained in great detail!
Helped A Lot
Thanks a lot for making such a nice tutorial. It cleared my doubts about view rendering in Yii, as i am new to yii and hunting for such tutorials, one of the best i got on view rendering.
Great
Its really a good wiki for beginners like me... Thank you very much.
Theme creation
Explained in great detail!
Awesome :-)
This is what a documentation should look like. (Not only) Yii developers can learn here ...
Thanks.
Good
Give clear idea about the structure,..superb..
Great
Thanks
Suggestion :)
Please pass @kenburcham info-graph, to the main article.
:) It help me a lot on the clarification.
ty
thanks ;)
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.