Help understanding the render process

I’m having problems passing variables to my rendered pages. This topic seems to be in several topics but none seem to touch on my particular problem. I have passed data to several other pages successfully but something eludes me from completely understanding what is happening.




public function actionSucesso($id)

{

	$model=$this->loadModel($id);


	$criteria = new CDbCriteria();

	$criteria->order = 'id DESC';

	$count=Frase::model()->count($criteria);

	$pages=new CPagination($count);


	// results per page

	$pages->pageSize=10;


	$pages->applyLimit($criteria);

	$listafrase = Frase::model()->findAll($criteria);


	//d($model);


	$this->render('sucesso', array('model'=>$model,'listaFrase'=>$listafrase,'pages'=>$pages));

}



NOTE: d() is just a custom dumping function.

This is a function inside ParticipeController.php, it functions fine for calling the view "sucesso" and rendering it. That is then passed the result as $content to my theme/layout gjmain.php. But when I try to use $model inside my gjmain.php it informs me that the variable is undefined.

So besides the obvious question "why is it undefined?" should it not pass those variable to gjmain as well? I am curious how it is calling gjmain, is that the default behavior for the render() (just to confirm my doubts)? Another questions that baffles me is why does gjmain render properly (passing values) for other parts of the site but fails here?

If by chance I have overlooked a previous topic, please forgive me. Thanks for your time!

The layout never gets view variables like your $model variable as the chain goes like this

  1. render() does a renderPartial() first and stores the rendered result in a variable (=>$content).

  2. The variable is passed to the layout.

  3. $content gets wrapped with the layout html.

So $content contains the already partially rendered result of your sucesso view that contains the $model variable. As it is rendered you can’t access any variables.

If you want to have access to a variable in your LAYOUT you have two options:

  1. Extend "Controller" (the one in your components folder) and add a public variable like "public $someText". This way all other controllers will inherit that one. In your layout you can then do $this->someText to get access to this variable.

  2. Use clips to basically do the same thing as in 1. See this wiki article http://www.yiiframework.com/wiki/127/dynamic-sidebar-using-cclipwidget

Ok, thanks I was thinking that was the case. The project I am working on was inherited from another team. this is my first go around with Yii and I wanted a better understanding to what was happening. I have just one more question. In another call in the same controller does a bit of magic. I have the following code:


public function actionFrase() {


	$model = new Frase;


	// Magic code with final call below


	$this -> render('frase', array(

		'model' => $model,

		'listaFrase' => $listafrase,

		'pages' => $pages

	));

}

the view "frase" is a single line.


<?php echo $this->renderPartial('_form', array('model'=>$model,'listaFrase'=>$listaFrase,'pages'=>$pages)); ?>

"_form" renders and is wrapped inside of "frase" and then finally "gjmain" (correct?).

Some how is call renders everything without problems, “gjmain” receives $model (from somewhere) without problems. Is the magic in the renderPartial(), which passes the variables the gjmain? Well I am just trying to understand how the previous team passed the values to gjmain. Their doesn’t seem to be any extended classes as you mentioned.

The previous layout is littered with vars and looks to require a rewrite of some of all the layouts to complement them. I am thinking that is what confused me most.

Once again many thanks!

There’s also a wiki here:

Understanding the view rendering flow