Views
A view is simply a web page, or a page fragment, like a header, footer, sidebar, etc. In fact, views can flexibly be embedded within other views (within other views, etc., etc.) if you need this type of hierarchy.
Views are never called directly, they must be loaded by a controller. Remember that in an MVC framework, the Controller acts as the traffic cop, so it is responsible for fetching a particular view. If you have not read the Controllers page you should do so before continuing.
Using the example controller you created in the controller page, let's add a view to it.
Creating a View
Using your text editor, create a file called blogview.lc, and put this in it:
<html>
<head>
<title>My Blog</title>
</head>
<body>
<h1>Welcome to my Blog!</h1>
</body>
</html>
Then save the file in your application/views/ folder.
Loading a View
To load a particular view file you will use the following function:
get rigLoadView("name")
Where name is the name of your view file. Note: The .lc file extension does not need to be specified unless you use something other than .lc.
Now, open the controller file you made earlier called blog.lc, and replace the put statement with the view loading function:
<?lc
# PUT YOUR HANDLER NAMES INTO THE GLOBAL gControllerHandlers AS A COMMA SEPARATED LIST
put "index" into gControllerHandlers
command index
get rigLoadView("blogview")
end index
If you visit the your site using the URL you did earlier you should see your new view. The URL was similar to this:
example.com/index.lc/blog/
Loading multiple views
revIgniter will intelligently handle multiple calls to rigLoadView() from within a controller. If more than one call happens they will be appended together. For example, you may wish to have a header view, a menu view, a content view, and a footer view. That might look something like this:
<?lc
# PUT YOUR HANDLER NAMES INTO THE GLOBAL gControllerHandlers AS A COMMA SEPARATED LIST
put "index" into gControllerHandlers
command index
put "Your title" into gData["pageTitle"]
get rigLoadView("header")
get rigLoadView("menu")
get rigLoadView("content")
get rigLoadView("footer")
end index
In the example above, we are using "dynamically added data", which you will see below.
Storing Views within Sub-folders
Your view files can also be stored within sub-folders if you prefer that type of organization. When doing so you will need to include the folder name loading the view. Example:
get rigLoadView("folderName/fileName")
Adding Dynamic Data to the View
Data in the global array variable gData is merged with the view. Here is an example using the gData array:
put "My Title" into gData["title"]
put "My Heading" into gData["heading"]
put "My Message" into gData["message"]
get rigLoadView("blogview")
Let's try it with your controller file. Open it and add this code:
<?lc
# PUT YOUR HANDLER NAMES INTO THE GLOBAL gControllerHandlers AS A COMMA SEPARATED LIST
put "index" into gControllerHandlers
command index
put "My Real Title" into gData["title"]
put "My Real Heading" into gData["heading"]
get rigLoadView("blogview")
end index
Now open your view file and change the text to variables that correspond to the array keys in your data enclosed in double square brackets:
<html>
<head>
<title>[[gData["title"]]]</title>
</head>
<body>
<h1>[[gData["heading"]]]</h1>
</body>
</html>
Note: Load the page at the URL you've been using and you should see the variables replaced.
Creating Loops / Using LiveCode in View Files
The data array in gData is not limited to simple variables. You can use multiple items or multi dimensional arrays, which can be looped to generate multiple rows. For example, if you pull data from your database it will typically be in the form of a multi-dimensional array, which you can combine to a list if you like.
Here's a simple example. Add this to your controller:
<?lc
# PUT YOUR HANDLER NAMES INTO THE GLOBAL gControllerHandlers AS A COMMA SEPARATED LIST
put "index" into gControllerHandlers
command index
put "Clean House,Call Mom,Run Errands" into gData["toDoList"]
put "My Real Title" into gData["title"]
put "My Real Heading" into gData["heading"]
get rigLoadView("blogview")
end index
Now open your view file and create a loop:
<html>
<head>
<title>[[gData["title"]]]</title>
</head>
<body>
<h1>[[gData["heading"]]]</h1>
<p>
<? put "<ul>" into tToDo
repeat for each item thisItem in gData["toDoList"]
put "<li>" & thisItem & "</li>" after tToDo
end repeat
put "</ul>" after tToDo
return tToDo ?>
</p>
</body>
</html>
Note: You'll notice that in the example above we are using a return statement enclosed in "<?" and "?>". Keep in mind, that this is the only way to include LiveCode in your view files. The last statement needs to be a return statement. All this means you can't use tags like "<?lc" or "<?livecode" or "<?lc" in view files because all views and nested views are merged (into the final output data).
As an example to include LiveCode in view files you typically would use return statements to display text from language files if you have various translations:
<html>
<head>
<title>[[gData["title"]]]</title>
</head>
<body>
<h1><? return rigLangLangLine("myInternationalHeading") ?></h1>
<p><? return rigLangLangLine("myInternationalBodyText") ?></p>
</body>
</html>
Returning Views as Data
There is a second optional parameter which lets you change the behavior of the function so that it returns data as a string rather than sending it to your browser. This can be useful if you want to process the data in some way. If you set the parameter to true (boolean) it will return data. The default behavior is false, which sends it to your browser. Remember to assign it to a variable if you want the data returned:
get rigLoadView("myfile", TRUE)
Nested Views Tutorial
Multiple views can be loaded sequentially by the controller or, as stated above, nested like in the following sample:
To keep it really simple, just to demonstrate how to embed views within other views, let's use the revIgniter welcome view and split it into three parts. We name them nestedviewsHeader.lc, nestedviewsContent.lc and nestedviewsFooter.lc.
nestedviewsHeader.lc, the header view:
<!DOCTYPE html>
<html>
<head>
<title>[[gData["pageTitle"]]]</title>
</head>
<body>
nestedviewsContent.lc, the content view:
<h1>Welcome to revIgniter!</h1>
<p>The page you are looking at is being generated dynamically by revIgniter.</p>
<p>If you would like to edit this page you'll find it located at:</p>
<code>application/views/welcomeMessage.lc</code>
<p>The corresponding controller for this page is found at:</p>
<code>application/controllers/welcome.lc</code>
<p>If you are exploring revIgniter for the very first time, you should start by reading the <a href="userGuide/">User Guide</a>.</p>
nestedviewsFooter.lc, the footer view:
<p><br />Page rendered in {{g_ElapsedTime_}} seconds</p>
</body>
</html>
Now we need one view which acts as the main view, the view all the other views are nested in. We name it nestedviewsMain.lc:
<? put rigLoadView("nestedviewsHeader", TRUE) into tHeader
put rigLoadView("nestedviewsContent", TRUE) into tContent
put rigLoadView("nestedviewsFooter", TRUE) into tFooter
return tHeader && tContent && tFooter ?>
Then, in the controller, we solely load the main view file to send a complete web page to the browser like in the following example:
<?lc
put "welcome,index" into gControllerHandlers
command welcome
# code...
end welcome
command index
# SET PAGE TITLE
put "YourPageTitle" into gData["pageTitle"]
# LOAD THE MAIN VIEW FILE
get rigLoadView("nestedviewsMain")
end index
--| END OF welcome.lc
--| Location: ./application/controllers/welcome.lc
----------------------------------------------------------------------
Of course, this way, nested views can be embedded within other views within other views etc., if you like.