Sunday, December 2, 2012

Render, Redirect and Variables with Yii

The primary purpose of a View is to display data and accessing data in the View is relatively easy. The easiest way to show how to do this is by example.

In your Controller there are various methods such as actionIndex, actionView, actionCreate etc. Let's break down a simple actionIndex for a model called Client.
public function actionIndex()
{
$dataProvider=new CActiveDataProvider('Client'); //first part
$this->render('index',array(                         //second part
'dataProvider'=>$dataProvider,                  
));
}
The first part of this method is loading data into the $dataProvider array. The second part is responsible for selecting/rendering the appropriate View and pushing the data into the View.

In the second part of the above method (the code responsible for rendering the view) you will notice the first parameter is 'index' and this is the View that will be displayed in the browser. The second parameter 'dataProvider' is the data that is sent to the View called 'index'. Lets look at the CController Class Reference and specifically the method called render().
public string render(string $view, array $data=NULL, boolean $return=false)
You will see the 'render' method takes 3 parameters - the name of the View (a string) , the data passed to the view (an array) and finally a boolean value which we won't worry about. This boolean value can be null (omitted) so it is not required. How do we access the data that is passed to the view? All we need to do is use '$data->property' where property is any of fields in the 'Client' table e.g. $data->name,
$data->address.

It is also possible to send more than one variable to the view and all you need to do is separate these variables with comma's.

public function actionIndex()
{
  $myVariable = "Hello World";
$dataProvider=new CActiveDataProvider('Client');
$this->render('index',array(                      
'dataProvider'=>$dataProvider,   'myVariable'=>$myVariable,            
));
}
To access this additional variable in the 'index' view you only need to refer to the variable name.
<?php echo "This is my variable - ".$myVariable; ?>

You will notice up until now we have been using the 'render' method of the class 'CController'. There is another method you will see in your controller called 'redirect()'. The 'redirect' method is a little different to the 'render' method in terms of how you access the data you push to the view.
public void redirect(mixed $url, boolean $terminate=true, integer $statusCode=302)
Let's just focus on the url parameter -  the documentation says basically that the url parameter can be just the URL to be redirected to OR if the parameter is an array, the first element must be a route to a controller action and the rest are GET parameters in name-value pairs. This means that when using the 'redirect' method the view can be passed to the method as an array along with any variables that need to be pushed to the view. An example of the syntax of the redirect method is:
$this->redirect(array('index','id'=>$model->id, 'myVariable'=>$myVariable,));
Notice that the view called 'index' is in an array with a variable called $myVariable which is a different syntax to the 'render' method. This is the trick - you cannot access the variable called 'myVariable' in the same way as previously with the 'render' method. As the documentation says you need to use the 'GET' method to access this variable. So in the view called 'index' you can access the variable called 'myVariable' by using the following:
<?php echo "This is my variable - ".$_GET['myVariable']; ?>
This is an important difference between the 'render' and 'redirect' method in a controller and is easy to overlook. To access variables pushed to a View, there is an important difference depending on whether the controller uses the 'render' method (in which case you access the pushed variables by the variable name) or the 'redirect' method (variables pushed to the view must be access by the GET method).

This is a good example of how important the Class Reference can be if you are having difficulty with a particular method. The reference may seem a little confusing however once you become accustomed to the syntax the explanation of the parameters can often resolve problems you may experience with a particular method.

References:

  1. Render Method
  2. Redirect Method


1 comment:

Unknown said...

hello.
i have one problem that i want pass a variable. i read your post but i not gerring you will u help me.

$this->redirect(array('create', 'SubCategoryID' => $model->SubCategoryID));

i want to call it and it's work good but on redirect it's display in url the id. so i want to remove it how can i remove it ?