Understanding Our Auto-Generated Code: Views

May 28, 2013

In this post, we discuss the views auto-generated by Gii.

By default, the views are generated in a folder under the views folder under protected, i.e. protected/views. The name of the folder generated is the same as the table name. For example, if the name of the table is users, like in our case, then the folder will be called users.

/**
* UsersController actionAdmin function
*/
public function actionAdmin() {
    $model = new Users('search');
    $model->unsetAttributes();  // clear any default values
    if (isset($_GET['Users']))
        $model->attributes = $_GET['Users'];

    $this->render('admin', array(
        'model' => $model,
    ));
}

The admin view is rendered from the render method. The render method accepts 3 parameters:

  • string $view - The name of the view to be rendered.
  • array $data - An array having the parameters to be sent to the view. (Optional)
  • boolean $return - whether the rendering result should be returned instead of being displayed. (Optional)

In the code snippet above, we’re rendering the admin view. And the data being sent is $model. The key used in the array is what will be used in the view. So in the case above, we’ll refer to the variable using the variable $model. If we used ‘userModel’ as the key in the array, we’d use $userModel in the view.

Partial Views are rendered using the renderPartial method. They are usually used within main views.

admin View

The admin view displays your data in a CGridView. It has the following items:

  • Breadcrumbs - This refers to the links that appear on the top of the users admin page

Yii Breadcrumbs

  • Menu - This refers to the links that appear on the side of the page. Menu contents are defined in an array having the following keys:
    • string 'label' - defines the text that will be displayed to the user, e.g. ‘Manage Users’
    • array 'url' - defines the URL for the link (i.e. the HTML href property). It’s usually defined in the format contoller/action, e.g. users/admin OR users/create. A custom URL can also be defined
    • array 'linkOptions' - defines any additional properties that should be added to the HTML Link Tag. For example, if we want the link to be opened in a new tab, we can add the key => value pair: 'target' => '_BLANK', so that the property target will be defined for the link. You can read more about Yii CMenu .
  • Some JavaScript - Yii registers some JavaScript here that will be used to control the ‘Advanced Search’ button. The function Yii::app()->clientScript->registerScript() is used to define JavaScript on the fly. In this case, some jQuery is used to bind a mouse click on the Advanced Search button to display and hide the Search form. It also binds the form’s submit function to update the CGridView below using AJAX.
  • A button to toggle the search form, and a partial render for the search form
  • The CGridView widget.

We’ll discuss the partial render and the CGridView in more detail.

CGridView

A CGridView is a Yii widget used to display data in a tabular form. Widgets in Yii are fetched using the widget() method.

/**
* CGridView widget
*/
$this->widget('zii.widgets.grid.CGridView', array(
    'id'=>'users-grid',
	'dataProvider'=>$model->search(),
	'filter'=>$model,
	'columns'=>array(
		'userID',
		'firstName',
		'lastName',
		'userName',
		'email',
		/*
		'status',
		'dateCreated',
		'insertedBy',
		'dateModified',
		'updatedBy',
		*/
		array(
			'class'=>'CButtonColumn',
		),
	),
));

The first parameter to the method is the alias of the widget; second is an array having parameters used by the widget. CGridView uses the following parameters as keys: id, dataProvider, filter, columns. More parameters are explained here.

Columns to be displayed are defined in the columns parameter. The data columns can be defined as:

  • a string representing the column name in the database, e.g. userID
  • an array representing CDataColumn properties, i.e. name, value, type, etc

Normally, we don’t want to display raw IDs to the users in our grid view, especially for cases where a value in a column is a foreign key of another table. For example, in our system, all tables have the column status. The value of the status column references a value in the entityStates table. So instead of displaying 1 in that field, we can display the corresponding entityStateName, i.e. ACTIVE

To do this, we need to ensure that the relation to EntityStates is defined in the Users model. First, use Gii to generate a model for the entityStates table. Then modify the relations function in the Users model to include a relation to EntityStates. The updated code should be as below:

/**
 * @return array relational rules.
 */
public function relations()
{
	// NOTE: you may need to adjust the relation name and the related
	// class name for the relations automatically generated below.
	return array(
		'studentProfiles' => array(self::HAS_MANY, 'StudentProfiles', 'userID'),
		'userGroupMappings' => array(self::HAS_MANY, 'UserGroupMappings', 'userID'),
		'status_' => array(self::BELONGS_TO, 'EntityStates', 'status')
	);
}

I normally append an underscore for BELONGS_TO relations to differentiate them from the HAS_MANY relations, in this case, status_.

Then update the users admin view file; add the string: status_.entityStateName.

If you refresh the users admin page view, you should see the entity state name in the status field.

Finally, we can change what is displayed as the header of the column having entity state Name to Status. In the Users model, update the attributeLabels() function to include the label status_.entityStateName. It’s value should be Status. The header for that column is now Status. Updated admin view page

The last item of the columns array is CButtonColumn. This defines the buttons that appear on the last column of the table. Additional properties can be defined to format how items are displayed on that column. You can read up on additional CButtonColumn properties here.

Also defined in the admin view is a partial render of the search form. _search.php is one of the partial views that was auto-generated in the users view folder. The renderPartial method takes the same parameters as the render method. In this case, the name of the partial view is _search, and the array contains the parameter that will be passed, i.e. model. If you go ahead and take a peek at the code in the _search.php file, you’ll notice that it is basically a form that displays some search fields. We’ll discuss the form fields when going through the _form partial view.

That’s it for this post. In the next one, we’ll discuss the other views.

Your questions, comments and suggestions are always welcome below.

NB: I’ve uploaded the code for this project on GitHub. Check it out (or clone :) here