-
Notifications
You must be signed in to change notification settings - Fork 1
3.8. Project Structure # Application Views
This folder contains the views of MMIR applications. Each controller can have a set of views which will be rendered by the PresentationManager
. The view definitions will be loaded automatically when the application is started. Additionally to the specific views, there is a folder containing the layout definitions. The MSK has one layout (application.ehtml
) which belongs to the Application
controller. This layout must exist, as it is used as default fallback: In General, each controller can have its own layout (but only one layout per controller) which is used when rendering the views of this controller. If there is no specific layout defined for a controller, the Application
layout is used by default.
In MVC based architecture, the view component is responsible for presenting the data to the user in a way that is "palatable" to the user, abstracting from the unnecessary details. In other words, any framework implementing and supporting the MVC pattern should provide means for to ease abstraction and presentation of the required data. This is also true for the MMIR framework, which follows the MVC pattern. The view definition should provide all necessary services for building a dynamic View component. The following are the main services provided by the views:
- Layout (will be described below)
- Templates (the views and partial views; will be described below)
- View Helpers (see chapter Application Helpers (
www/helpers
), p. 13)
When MMIR renders a view, it does so by combining the view with the controller's layout. If the controller has no specific layout defined, the Application
layout will be used instead. For defining layouts, you have access to 2 template expressions:
- Asset tags (i.e. template expressions
@script
and@link
) - Yield tags (i.e. template expression
@yield
) Note that in views (and partials) additional template expression can be used, see section View Template Expressions (p. 17).
Template expressions in layouts provide methods for generating HTML that link layouts to external JavaScript and stylesheet files. You can use these tags in layouts and even in views, although these tags are most commonly used in the <header>
section of a layout. Note that the asset tag helpers do not verify the existence of the assets at the specified locations; they simply assume that you know what you are doing and generate the link.
The @script
expression returns an HTML script
tag for each source provided. This helper generates a link to /assets/www/libs/
. For example, to link to a JavaScript file that is inside a directory called datebox
inside of the /assets/www/libs/
folder, you would do this:
@script("datebox/jpath")
MMIR will then output a script tag such as:
<script src='/libs/datebox/jpath.js' type="text/"></script>
The stylesheet_link_tag
helper returns an HTML link
tag for each source provided. This helper generates a ling to /assets/www/content/stylesheets/
. For example, to link to a stylesheet file that is inside a directory called ui_style
inside of the /assets/www/content/stylesheets/
folder, you would do this:
@style("ui_style/main")
MMIR will then generate the following link tag:
<link rel="stylesheet" hred="content/stylesheets/ui_style/main.css"/>
Within the context of a layout, yield
identifies a section where content from the view should be inserted. The simplest way to use this is to have a single yield
, into which the entire contents of the view currently being rendered will be inserted:
<html>
<head>
</head>
<body>
@yield("yield-name")
</body>
</html>
You can also create a layout with multiple yielding regions:
<html>
<head>
@yield("head")
</head>
<body>
@yield("content")
</body>
</html>
The main body of the view will always render into the unnamed yield. To render content into a named yield
, you should use the contentFor
method in your view definition.
The contentFor
method allows you to insert content into a named yield block in your layout. For example, this view would work with the layout that we just saw:
@contentFor("head"){
<title>A simple page</title>
}@
@contentFor("content"){
<p>Hello, MMIG! </p>
}@
The result of rendering this page into the supplied layout would be this HTML:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
</body>
</html>
The contentFor
method is very helpful when your layout contains distinct regions such as headers and footers that should get their own blocks of content inserted.
The framework allows an easy way of localization. It uses a dictionary to lookup the corresponding localized text for a supplied key:
<label for="login">
@localize("login_label")
</label>
Note that the language must be set and a dictionary exist, before the localization can be used properly.
On rendering the localize
part is replaced by the corresponding value for the currently set language. For the setting en
as language and an example dictionary, presented in section Add a new Dictionary, the result would be:
<label for="login">
Login
</label>
Commentary is surrounded by @*
and *@
. Comments will not be displayed in the rendered view in any way. All content that is within a comment section is not processed by the parser and will be removed before the view is rendered.
A little example of a commentary in action:
<html>
<head>
@* Here comes the title of the view *@
<title>A simple page</title>
</head>
<body>
@* and here is the body contents *@
<p>Hello, MMIG! </p>
</body>
</html>
This will result in:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
</body>
</html>
The commentary is simply removed.
Template variables can either be displayed in the view (see section **Rendered javascript **) or manipulated inside a JavaScript code segment – see following sections. The access to the variable is limited to the surrounding contentFor block of the view (see section Using @contentFor
). If the variable is used within a partial, it is accessable throughout the whole partial as a partial is an implicit contentFor section.
@var(title_string)
@{@title_string = "Title String"}
<html>
<head>
<title>@(@title_string)</title>
</head>
<body>
<p>>@(@title_string)</p>
</body>
</html>
The use of @var
and the @
prefix makes the variable's scope local for this template. This also means that no global variable with the same name is overwritten or the value from a global variable is used instead of a local created variable.
The variable will only be replaced by its value on rendering, if it is used inside a (rendered) javascript section – see section Rendered javascript code @( … ). Simply adding @variable to a view will just result in rendering @variable at this position – instead of the value of var.
> If a variable is used inside a javascript code block (unrendered or rendered), it should be initiated with `@var()` and referenced with `@` to ensure that the variable is not overwriting a global variable. > > Note that variables are not permitted inside a layout description.This expression evaluates the containing javascript code but does not render the return value. Inside the code block standard javascript can be used. See also the section about variables for a brief explanation about the scope of variables.
The following snippet is an example of how to use the unrendered javascript code:
@{@page_name = "simple page";}
@{
@dots="";
for (@i = 0; @i < 30; @i = @i + 1){
@dots = @dots + ".";
}
}
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
</body>
</html>
The first line simply assigns a value to the variable page_name
. The section beginning on the second line creates a string with 30 dots. All those commands are simply executed and nothing is going to be rendered in the final view. It will just look like this:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
</body>
</html>
This expression evaluates the containing javascript code and displays the return value into the location of the template expression. Inside the code block standard javascript can be used. See also the section about variables for a brief explanation about the scope of variables.
This example shows the usage of a rendered javascript code:
@{@page_name = "simple page";}
<html>
<head>
<title>A simple page with the name @(@page_name)</title>
</head>
<body>
<p>Hello, MMIG! </p>
</body>
</html>
The variable page_name
is replaced with the string assigned to it, resulting in the following code:
<html>
<head>
<title>A simple page with the name simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
</body>
</html>
As seen above, this construct is used to display template variable values.
> Note that the rendered javascript code block cannot contain multiple lines of code – it is mainly used for the display of template variables. In contrast, the unrendered javascript code can contain multiple lines of code.If a helper method is defined for a controller, it can be called from within a view. The helper's return value is then rendered into the view at the position of the helper call.
The syntax of the helper call is:
@helper(functionName [, params])
The function name is the name of the helper function. No controller has to be supplied – it is always the controller of the current view. The helper call can also be supplied with arguments via params
.
As the view is rendered, the helper method is called and its return value embedded in the currently processed view.
> If a `params` argument is passed to a helper method via the `helper` call, the data can be referenced inside the called helper by using the `arguments` variable. This variable holds the arguments of the helper call.This snippet calls a helper method named createListElements
with some arguments and puts the return value in place of the method call:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
@helper('createListElements', {obj1 : 'value1', obj2 : 'value2'})
</body>
</html>
To insert a partial anywhere in the view, the @render
statement is used. This processes the referenced partial and displays the rendered result at the position of the call.
The syntax for the @render
statement is:
@render(controllerName, partialName, data)
The controllerName
is the name of the controller which is associated with the partial, while the partialName
is the name of the partial.
The data
argument allows for the passing of arguments to the partial, e.g. ascertained by a helper method. The type of the data argument can be one of the following: a string / number literal, template variable or a JSON like object, which itself can consist of an array, string / number literal and a JSON like object.
This render call of a partial may display a menu to select a language and supply a title as well as a personal salutation to the user:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
@render('Application', 'languageMenu', {displayTitle : true, salutation : "Bob"})
</body>
</html>
Inside the partial languageMenu
, the data of the render call, {displayTitle : true, salutation : "Bob"}
, may be referenced via the @argument
variable.
TBD: add details and examples for template expressions (see example for partial in /views/application/~languageMenu.ehtml).
For the control of the rendered view output, the @if
construction can be used to display parts of the code only if a defined condition is true.
The syntax is:
@if (javascript condition) {
part to display if condition is true – view expressions or HTML
}@ [ @else{
part to display if condition is false – view expressions or HTML
} @ ]
The else-part is optional. Inside the if segments all view expressions, including HTML, can be used.
An example of a conditional rendering:
@{@debug = true;}
<html>
<head>
@if(@debug == true){
<title>Debug mode</title>
@{@debug_time = new Date();}
}@ @else {
<title>A simple page</title>
}@
</head>
<body>
<p>Hello, MMIG! </p>
@if(@debug == true){
<div id="debug_info"></div>
}@
</body>
</html>
This would result in the rendered view:
<html>
<head>
<title>Debug mode</title>
</head>
<body>
<p>Hello, MMIG! </p>
<div id="debug_info"></div>
</body>
</html>
For the generation of similar view sections, e.g. menu items, the @for
statement can be used. The @for
statement can be used in two ways: to iterate over an object or it is used as a counter.
The syntax is:
@for (initialization; condition; afterthought) {
loop body
}@
@* or: *@
@for (item in object) {
loop body
}@
The following snippet creates a list of the work days of the week by using a counter:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
@{ @daysArray = ["mon", "tue", "wed", "thu", "fri"]; }
<ul>
@for(@i=0, @size = @daysArray.length; @i < @size; ++ @i){
<li>@(@daysArray[@i])</li>
}@
</ul>
</body>
</html>
This results in:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
<ul>
<li>mon</li>
<li>tue</li>
<li>wed</li>
<li>thu</li>
<li>fri</li>
</ul>
</body>
</html>
The same can be achieved by using the iterative way of the @for
statement:
<html>
<head>
<title>A simple page</title>
</head>
<body>
<p>Hello, MMIG! </p>
@{ @daysArray = ["mon", "tue", "wed", "thu", "fri"]; }
<ul>
@for(@i in @daysArray){
<li>@(@daysArray[@i])</li>
}@
</ul>
</body>
</html>
If the at sign, @
, should be displayed in the view, it must be "escaped" by another @
: @@
will display @
.
Inside a called helper function or rendered partial, the supplied data can be referenced by either referencing the arguments
variable inside the helper function or referencing the @argument
template variable inside a partial.
A partial can reference the supplied arguments easily with the @argument
template variable:
<div>The supplied arguments are: @(JSON.stringify(@argument))</div>
Inside a helper function, the supplied arguments can be referenced by the arguments
variable:
var args = arguments;
for (var a in args){
// process the arguments
}
If a call to render a view is also supplied with arguments, these can be accessed with the @data
template variable. Calls to render views are typically generated by the state machine and can be supplied with additional parameters to create contextual rendered output.
A call to render the loginManager
view may look like this:
dialogManager.render('Application', 'login', {languageMenu : true});
Inside the view login
, the property languageMenu
can be accessed by referencing to @data.languageMenu
, which will yield true
.
Footnote | Description |
---|---|
[∗] | The Apache Cordova project was started off with the donation of code from PhoneGap. Now PhoneGap is a distribution using the Open Source code base of Cordova. |
[†] | Source: http://phonegap.com/about/feature/ |
[∞] | see ISO 639-1 specifiaction |
[⊗] | Eclipse Classic does not bring an editor HTML by default; you can install an editor manually e.g. using your Eclipse’s update page (Install New Software...) http://download.eclipse.org/releases/[version_name], expand the entry Web, XML and Java EE development and select Web Page Editor. |
[⊥] | Note, that currently no source code is available for Android ver. 3.x. |
[Θ] | the file build.properties contains general settings for build.xml , which do not need to be customized to the specific project environment. |
[◊] | see http://nodejs.org/ |