Difference between #12 and #11 of Understanding the view rendering flow

unchanged
Title
Understanding the view rendering flow
unchanged
Category
FAQs
unchanged
Tags
layouts, views, render, renderPartial, variables, beginContent, understanding
changed
Content
Introduction
------------------
There are many confusions regardingis a lot of confusion
surrounding what is happening behind the scenes when you render a view.

If we take a look at the blog demo we have 3 major parts of our view
rendering and theyrendering. They are:

**1)** The layouts/column1 and column2 that look like (column1.php
and column2.php):

~~~
[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



~~~
[php]
<!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 ,render, for example
site/contact



~~~
[php]
<?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 looks like the following:-
following:

~~~
[php]
/**
	 * Displays the contact page
	 */
	public function actionContact()
	{
		$model=new ContactForm;
		//some form code was here...
		$this->render('contact',array('model'=>$model));
	}
~~~
<center>
![](http://i31.fastpic.ru/big/2011/1007/07/c149a80587fa51c23bd77ed9fa6a3007.jpg
"")
</center>
The
The common questions and confusionscauses of
confusion we will address:
----------------------------
**1)** WhyWhy, if I pass the
contactcontact.php some $test variable like 
$this->render('contact',array('model'=>$model,'test' => 123));
and I echo it in the layout with echo $test, do I get error 500
undefind variable error?

**2)** I didn't pass any $content variable so what is

~~~
[php]
<?php echo $content; ?>
~~~

doing inside the beginContent tags of column1.php ?

**3)** Why does the layouts/main.php haveWhat is $content in
layouts/main.php?
~~~
[php]
<?php echo $content; ?>
~~~

I didn't pass suchset this variable...

**4)** Why do both column1.php and main.php echo the $content
?$content?

**5)** Why does setting the title inside contact.php change the
variablevalue of $this->title in main.php?

~~~
[php]
<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
?there? ;-)
<center>
![](http://i31.fastpic.ru/big/2011/1007/f2/9e5cad7302eff04bf37d2022aa5178f2.jpg
"")
</center>
Diving in the source code
-------------------------
You have two options:<br>
**1)** You can accept the rules and follow them without understanding<br>
**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, let's dive together...
<center>
![](http://i30.fastpic.ru/big/2011/1007/a8/499d3a96c8746dfd8748e8f0d8ced1a8.png
"")
</center>
Every good IDE has the ability to go directly to the function by pressing ctrl
and  the function name...

So lets go to SiteController.php, to the actionContact and press the render word
at this line:

~~~
[php]
$this->render('contact',array('model'=>$model));
~~~

After pressing you will find yourself inside yii/web/CController.php on line 775

~~~
[php]
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 are talking about the blog demo, no preprocessing
there, so it just returns true...

~~~
[php]
protected function beforeRender($view)
	{
		return true;
	}
~~~


After we got true, we can continue ...

We have,

~~~
[php]
$output=$this->renderPartial($view,$data,true);
~~~

So our 'contact' view is rendered partially, with third parameter as true, this
means that the result is 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 was processed

After this, if a layout is defined

~~~
[php]
if(($layoutFile=$this->getLayoutFile($this->layout))!==false)				$output=$this->renderFile($layoutFile,array('content'=>$output),true);
~~~

weWe 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.
<center>
![](http://i29.fastpic.ru/big/2011/1007/70/de7df52fc8e9032c0993f5ad2396ce70.jpg
"")
</center>
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]
<?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]
<?php echo $content; ?>
~~~

Don't passed such variable...

**Answer:**

~~~
[php]
<?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)** whyWhy, if I make a change inside
contant.phpto the title,title inside
contact.php, does it changes the main.phpvalue of
$this->title variable ?in main.php?

~~~
[php]
<title><?php echo CHtml::encode($this->pageTitle);
?></title>
/* in contact.php $this->pageTitle=Yii::app()->name . ' - Contact Us'; */
~~~

**Answer:**

asAs we saw, the contact.php is rendered before the
layout, so every field( akafield (aka class parameters),
you change from the view file (contact.php) will effect the layout because
itit's rendered after...afterwards.

#### And the main confusion:
**6)** whatWhat is called before what?
whatWhat the heck is going on there ? ;-)
<center>
**contact.php (passed as content)-> column1.php (passed as content)->
main.php**
</center>
<center>
<img
src="http://i30.fastpic.ru/big/2011/1007/21/6c07cda81e332dba19bd59a812abc121.png"
width="750"/></center>
That's it, now you are now pro inat
layouts ;-)