Rendering View Files in Yii

February 15, 2011 — 48 Comments
The Yii Book If you like my writing on the Yii framework, you'll love "The Yii Book"!

In the MVC architecture, the Controller reacts to a user request. In doing so, the Controller often loads an instance of a particular Model and then renders a specific View. “Rendering” just means compiling all the pieces together, including static text (HTML and such) and the output from executed PHP code. For example, when a user goes to a page for updating a record, the Controller loads the associated record, and then renders the “update” View, which will display the pre-populated form:

public function actionUpdate($id) {
    $data=$this->loadModel($id);

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

Note: That method would also have code in it for handling the submission of the update form, but I’m trying not to complicate the discussion.

As you can see in that code, the render() method, defined in the CController class, is how a View file is chosen for rendering. The first argument to the method is the View file to be rendered, without its .php extension. The render() method will render the View file within the appropriate layout file. In other words, the View file will be rendered with its context. The above code renders update.php, for the associated Controller, wrapped within the views/layouts/main.php layout file (the default).

The second argument to render() is an array of data that can be sent to the View file. In the above code, the Model instance is being passed along. In update.php, references to the $model variable will refer to the loaded data (note that the View gets its variable names from the indexes used in the array).

The render() method takes an optional third argument, which is a Boolean indicating if the rendered result should be returned to the Controller instead of sent to the Web browser. This would be useful if you wanted to render the page and then send the output in an email or write it to a text file on the server (to act as a cached version).

Sometimes you’ll want to render a View file without incorporating the layout. To do that, invoke renderPartial(). For example, both the update.php and create.php View files, auto-generated by Yii, just provide a context, and then include the form file:

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

Since the initial View file will have already be rendered within the layout context, the layout shouldn’t be rendered again. The renderPartial() method will render just the named View file. Its second argument, as with render(), can be used to pass data to the View file. In the above, the Model instance is passed along.

Tip: The renderPartial() method is also used for Ajax calls, where the layout isn’t appropriate.

As mentioned already, the file being rendered comes from the directory associated with the current Controller. For example, when updating an Employee record, the URL is something like www.example.com/index.php/employee/update/id/23. This calls the actionUpdate() method of the EmployeeController class (whose code is partially shown above). That method renders the “update” View, which is to say protected/views/employee/update.php. But there are rare cases where you’ll need to render View files from other subdirectories. For example, you may want to include a search form on a page, with that form found within another View directory. To change the reference point, start the View reference with a double slash, which means to start in the views folder. Then indicate the subdirectory and file, still omitting the extension:

<?php echo $this->renderPartial('//search/_form'); ?>

And that’s all there is to it!

View rendering is one of the most important concepts to grasp in an MVC design. Fortunately, it’s not that hard to follow in Yii. Just remember that if you want your layout file, use render(). If not, use renderPartial(). If you need to pass data to the View file, use the second argument to send along an array, whose indexes will become the names of the variables within the View. Finally, if you need to change the include path, begin with a double slash.

If you enjoyed this post, then please consider following me using your favorite social media, the RSS feed, and/or by subscribing to my newsletter. Or go crazy, and buy one or more of my books . Thanks!

48 responses to Rendering View Files in Yii

  1. Just a formatting comment: in firefox, and chrome (ubuntu) the code formatting you use in the samples, makes underscore dissapear and //search/_form looks like //search/ form
    Besides that, great article!

  2. Jamil Najafov March 1, 2011 at 2:47 pm

    Same in chrome (win7 64bit).

  3. Thanks for the excellent article.
    Is your blog coded in Yii?

    -Mukesh

  4. hey larry , I have one doubt , suppose I have two model called user and profile. I want to render the view of profile model on user view page. So how to do that. Any help will be highly appreciable.

  5. Hello Larry,
    Couple of serious questions .
    1) Are you seriously a human ?
    2) If so does god give you 50 hours per day ?

    I don’t have any other words to appreciate your work .

    God bless You .

  6. Brilliant, nice and clean explanation – huge thanx to Larry!
    Wanted to ask you to write something about main concepts of widget’s creation (login form that’s always on the site, mini news-block etc) or give me a link to best explanations of the subject (but no one can really better do it than you : )

  7. Manuel Paniagua October 14, 2011 at 9:01 pm

    Hi Larry, first let me tell you I really appreciate all your yii tutorials, they really have pointed me in the right direction since I only have like 2 days working on it….Thanks.

    Now I have a quick question, I have a family view that displays all the info from the family and in addition displays some info from the childs of that family, I managed this with a CListview in the family view with a call to childs data, now that CListView creates a link with the id of the child but when you click on it it sends me to the family view trying to find the child data, how do I change that link so it sends me to the childs data view?? any ideas?

    • Thanks, Manuel. In answer to your question, you’d change that link by customizing the CListView.

      • Manuel Paniagua October 18, 2011 at 1:26 pm

        Actually Larry, its not the CListView, its the _view that the CListView renders that has to change. I mean when you use ‘itemView’=>’//hijo/_view’ you have to change the view from
        Codigo), array(‘view’, ‘id’=>$data->Codigo)); ?> to Codigo), array(‘//hijo/view’, ‘id’=>$data->Codigo)); ?> that way you dont change the whole CListView just the link. I just found out that a couple of minutes ago :0).. thanks for taking the time to answer anyway

  8. Hi Larry, you have done a really amazing job. I was wondering if there was a way to display the text from the mysql table as bold italic etc. without the tags i.e. as they are?

    • Thanks for the nice words. In answer to your question, if I understand you correctly, you just need to edit the HTML in the View files or edit the corresponding CSS.

  9. Daniel O’Donnell February 29, 2012 at 9:44 pm

    There is one aspect of this that might be worth mentioning, since it seems to be a common problem: the question of whether you can use this method to pass parameters to the view itself–i.e. whether you can use the $data array to pass on something arbitrary like ‘test’=>123 that you want to use in the view.

    As I understand this from here, this isn’t possible. renderPartial('_form', array('model'=>$model,'test'=>123)); ?> will not allow you to include a echo $test in your view. Instead you’ll get a 500 error.

    If you want to pass parameters to a view (for example, if you want to use an actionCreate but pre-fill some attributes from the referring page), you need to build this into the action and you need to capture the parameters in the controller or the view. There are several ways of doing this: one is to use a Yii param (though I confess I don’t know that very well, yet). The other, I think, is to include it in the post or get and modify the controller action you are invoking so it recognises the parameter(s) you are passing.

  10. i have a doubt..what i need is..i want to create a view page that including datas from two models..
    how is that possible?
    will you please help me?

    • That is possible. You just need to create a relationship between the two models so you can bring the second one in.

      • Frank San Filippo March 29, 2012 at 7:48 pm

        Can you follow up on this? I am trying to do that with a model that has a many to many relationship to another model through a third module. When I try to access the update function for the first model, I get a CDbException saying Relation “{{uid_lid_join}}” is not defined in active record class “Contact”.
        (uid_lid_join is the table referenced in the Contact model, thusly:
        ‘lists’ => array(self::HAS_MANY, ‘Lists’, array(‘uid’=>’uid’), ‘through’=>’{{uid_lid_join}}’),

  11. This has got to be the clearest, most awesome article I have read about the Yii framework. Thanks!

  12. Frank San Filippo April 5, 2012 at 8:25 pm

    I did figure out what my issue was. It wasn’t clear to me that the “through” was supposed to be another pre-defined relation; I thought it was supposed to be a table name.

    Thanks for all the good work!

  13. Could you please post an example for rendePartial via ajaxButton?

    Thank you so much

    • I’m not exactly sure what you mean. renderPartial is on the server-side of things. Ajax would start in the client. Not sure what connection you’re trying to make here.

  14. Thank you for good article. You have made my evening gud.

  15. i am trying load my main layout with small changes in the header content like email and password column into username and points after logging in. Larry can u tel me how to do this with the same layout……..

  16. Why use render function with parameters to be passed like variables when you can simply use require or include directive. The variables would be visible in included files too.

    Instead of :
    $this->render(‘update’,array(‘model’=>$data));

    Wouldn’t be more simple:
    $model = $data;
    include ‘update.php’;

    • It would be more simple, yes, but it wouldn’t work at all. That’s not how frameworks work, and not how MVC is done. If you were to do what you recommend, at the very least, the output would not contain any of the primary layout material. To emphasize the point: a simple require or include will not work at all.

    • To follow up on what Larry just posted, when dealing with a framework such as Yii, you should use the framework as much as possible in order to take advantage of it. Using an include statement would not benefit you in the long run, especially when Yii has methods available to use for this. If you build anything of size without using the framework to the fullest, I think you would find yourself going back and changing code as you get more familiar with the framework.

      I cannot honestly think of an example when you would use include over render.

      • What advantages are you referring to? What benefits are in the long run?

        • Well in this specific example, ‘include’ would only display the contents of ‘update.php’ and nothing else at the very best. If you use the frameworks render function, the contents of ‘update.php’ would be displayed as well as the contents of the layout you are using and any of the layout’s partials. Also, Yii was built as a MVC framework. What you speak of goes against the conventions of MVC. If you do not treat ‘update.php’ as a view, it would be hard to understand your code. Following standard MVC practices would make your code more readable, which is a huge advantage in the long run.

  17. Larry, I have an odd question regarding my view files.

    I have a site that I maintain that lets volunteers sign up for trips. Each trip has an id and reside all in their own table. But, when I try to view them “…/trip/id# only the trips from 1 – 17 show up. Everyone greater than 17 gives me a “page not found” error.

    The action file (view) is basic. I haven’t changed it. There is nothing in the view file that cares what the id number is. It takes whatever is given. I am stumped. I have been banging my head for days.

    Do you have any ideas you can point me to?

  18. Is there any way to show a view without using render / renderPartial methods ?

  19. Hey Larry, Thanks a lot for your Yii articles. Would like to clarify a doubt. How can I not associate a controller action with a view, that is, I just want the template to be rendered. Do I need to use $this->render(‘file’), where file has no contents ? Is it mandatory to associate a controller action with a view ?

    • Thanks for the nice words. I’m not sure exactly what you’re wanting to do, but my hunch (based upon the way your question is written), is to say that you must associate a controller action with a view.

  20. HI Larry,

    I am trying to create a dynamic menu and for that i have created a module namely menu.

    Now you please tell me how i render a view of module menu in main layout file????

  21. hi
    lerry
    you doing well job but if you wanthelp more peoples then just make a hindi virsion too of your all pages .. :D

  22. sorry fo the irrelevant question.how to show two register forms in a single view with tabbed html

  23. I want to add task/admin in site/index view.

    I have done like this

    $this->renderPartial(‘application.views.task.admin’,array(‘model’=>$model),true);

    It’s working.

    But, In task/admin, below code gives error “SiteController cannot find the requested view “_search”. ”

    $this->renderPartial(‘_search’,array(
    ‘model’=>$model,
    ));

    So i have changed it to (In /task/admin)

    $this->renderPartial(‘//task/_search’,array(
    ‘model’=>$model,
    ));

    So I want to know that, Is this proper way to do it?

    My admin view edit, view, delete link are current controller link
    e.g. i have added /task/admin in site/index so links are
    Edit :: urltoapplication/site/update/5
    View :: urltoapplication/site/5

    how to change them to task controller?

Comments are great, but I'd strongly prefer any requests for assistance get made in the support forums. Thanks!