Last week I described how requests to Garden are handled by the dispatcher. This week Icheap xenical 17;m going to explain how those requests are rendered by the requested controller.
Once a controller method is called to handle the request, how is the xhtml of the page put together? cheap xenical.
There are two types of views in Garden: cheap xenical cheap xenical 0;Viewscheap xenical cheap xenical 1; and cheap xenical cheap xenical 0;Master Viewscheap xenical cheap xenical 1;. A view relates directly to the controller method that called it and handles rendering content related to that request. You can typically think of a view as the content for that page. For example, if a Vanilla->Discussion->All() method is called, the view for that method would handle rendering all of the discussions. Everything that is rendered around the discussions is handled by the Master View.
The Master View allows you to create a consistent layout for the pages in the application. A single master view defines the look and feel and standard behavior for all of the pages (or a group of pages) in the application.
Letcheap xenical 17;s go back to the filesystem so you can get a better picture. In the following example, the request in the url would have been the following:
http://myserver.com/garden/profile/index/mark
So, this means that Gardencheap xenical
17;s cheap xenical
cheap xenical
0;Profilecheap xenical
cheap xenical
1; controller was requested, the cheap xenical
cheap xenical
0;indexcheap xenical
cheap xenical
1; method was requested from the profile controller, and the first argument into the index method is cheap xenical
cheap xenical
0;markcheap xenical
cheap xenical
1;. In other words, the request was: $ProfileController->Index('mark');

Letcheap xenical 17;s take a look at the profile controllercheap xenical 17;s index method:
public function Index($UserReference = '') {
$UserModel = new UserModel();
$this->User = $UserModel->GetByReference($UserReference);
$this->Render();
}
Simply put, the index method grabs some data that can be later used in the profile controllercheap xenical 17;s cheap xenical cheap xenical 0;indexcheap xenical cheap xenical 1; view, and then calls the Render() method. The Render method is defined on the base Controller class; the class from which all controllers are extended. The Render method performs the following tasks:
1. Finds and fetches the view.
cheap xenical
. Finds and fetches the css for the view.
3. Finds and renders the master view.
In the most simple example, the view will be as it appears in the image above: in a cheap xenical cheap xenical 0;profilecheap xenical cheap xenical 1; folder within the cheap xenical cheap xenical 0;viewscheap xenical cheap xenical 1; folder, and named after the method that was called: cheap xenical.
By default, the controller will fetch that view from the context of the FetchView method of the base controller class. In plain-English: the view file is included within a method on the Controller class called cheap xenical cheap xenical 0;FetchViewcheap xenical cheap xenical 1;. That is why I placed the user data within a $this->User property in my $ProfileController->Index() method, above; so it could be accessible from within my view file. The view file likely will contain something as simple as this:
<h3>Basic Information</h3> <dl class="Info"> <dt>Joined</dt> <dd><?php echo $this->User->DateFirstVisit; %3F></dd> <dt>Visits</dt> <dd><?php echo $this->User->CountVisits; %3F></dd> <dt>Last Active</dt> <dd><?php echo $this->User->DateLastActive; %3F></dd> </dl>
cheap xenical
Once the view is fetched, it is added to an asset collection. By default it is added to the cheap xenical cheap xenical 0;Contentcheap xenical cheap xenical 1; asset collection. The rest of the page (the cheap xenical cheap xenical 0;Framecheap xenical cheap xenical 1; of the page) is handled by the master view. By default, the cheap xenical cheap xenical 0;default.mastercheap xenical cheap xenical 1; master view is used unless another master view is specified. In the image above you can see that there are a few different master views available in the Garden application: default, email, error, and setup. The css files for each of those master views are named accordingly, as well. So, the default.master view has a default.screen.css file, the error.master view has an error.screen.css file, etc. Again, in the most simple of examples, the master view is located in the cheap xenical cheap xenical 0;viewcheap xenical cheap xenical 1; folder of the application, and the related css files are located in the cheap xenical cheap xenical 0;designcheap xenical cheap xenical 1; folder of that application.
Here is what the default.master view looks like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-ca">
<head>
<?php $this->RenderAsset('Head'); %3F>
</head>
<body<?php echo Attribute(array('id' => $BodyIdentifier, 'class' => $this->CssClass)); %3F>>
<div id="Frame">
<div id="Title"><a href="<?php Link('garden/user/browse'); %3F>"><span><?php echo $this->Head->TitlePrefix; %3F></span></a></div>
<?php $this->RenderAsset('Menu'); %3F>
<div id="Content"><?php $this->RenderAsset('Content'); %3F></div>
<div id="Foot"><?php $this->RenderAsset('Foot'); %3F></div>
</div>
</body>
</html>
As you can see, the master view handles the basic structure of a page. As I mentioned above, by default the view that is fetched by the controller is added to an asset collection called cheap xenical
cheap xenical
0;Contentcheap xenical
cheap xenical
1;, and that asset collection is rendered in this master view when the $this->RenderAsset('Content') method is called cheap xenical
11; right there in the middle of the master view.
As you can see in the master view above, there are a number of different asset collections available for application and plugin authors (Head, Menu, Content, and Foot). An application author has the ability to add as many of these as he/she desires and add to them as necessary. The idea behind these asset collections is that while the basic request can be handled and placed into the cheap xenical cheap xenical 0;Contentcheap xenical cheap xenical 1; asset (ie. the profile information being displayed from the example above), there are still a lot of other elements a person may want on a page. Plugin authors may want to add assets to the head, menu, or foot. They may even want to add assets to the content collection. Garden itself has other UI components that get rendered in the head and menu asset collections (which will be discussed in a later preview).
So, in the most basic example, the cheap xenical cheap xenical 0;indexcheap xenical cheap xenical 1; view is requested from itcheap xenical 17;s controllercheap xenical 17;s view folder, the default.screen.css file is requested from the applicationcheap xenical 17;s design folder, and the master view is requested from the root of the applicationcheap xenical 17;s cheap xenical cheap xenical 0;viewcheap xenical cheap xenical 1; folder. What other ways could the views and css have been retrieved?
The controller uses Gardencheap xenical 17;s FileSystem object to search the application for the appropriate file to handle the request. Whatever the filesystem object finds first, it will use.
cheap xenical
cheap xenical
ie. a plugincheap xenical
17;s custom view location
cheap xenical
ie. /path/to/garden/themes/theme_name/app_name/views/controller_name/view.php
cheap xenical
ie. /path/to/garden/themes/theme_name/views/controller_name/view.php
cheap xenical
ie. /path/to/garden/applications/app_name/views/controller_name/view.php
cheap xenical
cheap xenical
ie. /path/to/garden/themes/theme_name/app_name/views/default.master
cheap xenical
ie. /path/to/garden/themes/theme_name/views/default.master
cheap xenical
ie. /path/to/garden/applications/app_name/views/default.master
cheap xenical
ie. /path/to/garden/applications/garden/views/default.master
cheap xenical
cheap xenical
ie. /path/to/garden/themes/theme_name/app_name/design/default.screen.css
cheap xenical
ie. /path/to/garden/themes/theme_name/design/default.screen.css
cheap xenical
ie. /path/to/garden/applications/app_name/design/default.screen.css
cheap xenical
ie. /path/to/garden/applications/garden/design/default.screen.css
You might be wondering things like: can I change the view or master view that handles my request on the fly? Of course you can! Everything in Garden was written so that you have total control over what comes out on the other end. In my example above, I could change my views on the fly with something like this:
public function Index($UserReference = '') {
$UserModel = new UserModel();
$this->User = $UserModel->GetByReference($UserReference);
$this->View = "somethingelse"; cheap xenical
$this->View = "/some/other/view.php"; cheap xenical
$this->MasterView = "setup"; cheap xenical
$this->Render();
}
Views are a lot to take in, and they certainly might be daunting upon first read. But I can guarantee that I have found them to be utterly simple and flexible to use. Think of the possibilities you can accomplish with views! You could create a master view that handles rendering of RSS feeds. You could port your request method to use your RSS master and render all of your contents with a custom RSS view. You could grab the email master view and send out your content to some email address(es) before rendering. You could bypass the rendering altogether and deliver json data. The possibilities are endless, and that is the real power of views.
