Views & Templates
In the MVC concept all output is done via views. In this chapter we show you how views can be worked with in n2n!
Calling a View
So far we have only worked with controllers. In the MVC concept it makes no sense to make output directly in the controller! In MVC the views are responsible for the output. So next we will look at how views are called.
Creating Views
First we create our directory for the views:
app/qs/view
In principle it does not matter in which directory views are located. But we recommend storing all views in a /view directory. If you have a module with many views, you can create subdirectories.
In the created directory we create the following files:
app/qs/view/overview.html.php
<h1>Our Blog Articles</h1>
<p>Here follow the articles</p>
app/qs/view/detail.html.php
<h1>Detail View</h1>
<p>Here comes a single article</p>
app/qs/view/thanks.html.php
<h1>Thanks</h1>
<p>Thank you for your comment</p>
<a href="javascript:history.back()">Back</a>
The following can be noted about views. Views are not classes, but simple PHP files. The output format is indicated before the .php extension. Because we have HTML output everywhere, all our views end with .html.php.
Calling Views
Now you can call your views via the controller. Replace the methods index(), detail() and doThanks() as follows:
public function index() {
// 1.) call with a relative path
$this->forward('..\view\overview.html');
}
public function detail(string $urlPart) {
// 2.) call from the module path
$this->forward('~\view\detail.html');
}
public function doThanks() {
// 3.) call via the full namespace --> always starts with \
$this->forward('\qs\view\thanks.html');
}
As you can see, the controller calls the views with $this->forward(). There are three ways how the path can be given: either relative from the current namespace (1), from the module namespace (2) or absolute with the full namespace (3). With the relative path you give the path from the location of the controller. With the absolute path you start with a backslash and then give the full namespace. Note: we are moving in the namespace, therefore we use the backslash. With the full namespace views outside of the module can be called as well!
Attention
We recommend calling module-internal views with a relative path or from the module namespace. Module-external views should always be called with a leading backslash and the full namespace.
Your First Template
Of course our previous view does not yet produce a complete HTML file. We want to change this now by creating a template that we use for all views.
In reference to HTML5-Boilerplate we name the file \qs\view\boilerplate.html.php
<?php
use n2n\impl\web\ui\view\html\HtmlView;
use n2n\web\ui\view\View;
use n2n\core\N2N;
// 1. objects of the view: not strictly necessary
$view = HtmlView::view($this);
$html = HtmlView::html($view);
$request = HtmlView::request($view);
// 2. read out the title and the description
$title = $view->getParam('title', false, 'Example');
$description = $view->getParam('description', false);
// 3. fill the tags in the header area
$html->meta()->setTitle($title);
$html->meta()->addMeta(array('charset' => N2N::CHARSET));
if (null !== $description) {
$html->meta()->addMeta(array('name' => 'description', 'content' => $description));
}
?>
<!doctype html>
<html lang="<?php $html->out($request->getN2nLocale()->getId())?>">
<?php $html->headStart() ?>
<?php $html->headEnd() ?>
<?php $html->bodyStart() ?>
<?php $view->importContentView() ?>
<?php $html->bodyEnd() ?>
</html>
In every HTML view the objects $view, $html and $request are automatically available. We note the first three lines so that your IDE recognizes the objects and does not output warnings.
$viewprovides methods of theHtmlView. Typically you can use$viewto access the parameters that were passed to your view, or you can determine the template or import further views.$htmlis aHtmlBuilder. Via$htmlyou can produce HTML output. For example, with$htmlyou determine where<body>starts and ends. You can also pass external resources to$html(e.g. JavaScripts or CSS) that have to be loaded. Also very important:$htmlhelps you output content safely (for example with the method->out()).- Via
$requestyou can access information about the HTTP request.
With $view->getParam() you can read out parameters that are passed to a view. We check whether a title and a description were passed for this page. We do not strictly expect either (cf. false in the second parameter). For the title we set a default value with 'Example'.
In the third step we set the title, read out the charset from the app.ini (by accessing the N2N class) and check whether a description was passed.
In the html tag we get the active n2n locale via $request. By the way, the default locale is set in the app.ini of the application and can be adjusted there.
Attention
We never use
echoin views. All output that should be safe is done via$html->out(). You will notice the difference when you try out$html->out('<script>alert("test");</script>').
Note that we open and close the <head> and <body> tags with the $html object. The reason for this is that other views can add scripts and tags for the head and body area, and these are only output when you open and close the <head> and <body> tags as shown.
With $view->importContentView() the view that invoked the template is included. Now we only have to call the template from the views.
To do this, add the following PHP code at the very top of all previous views (overview.html.php, detail.html.php and thanks.html.php):
<?php
use n2n\impl\web\ui\view\html\HtmlView;
use n2n\web\ui\view\View;
// optional line
$view = HtmlView::view($this);
// instruction to use the template
$view->useTemplate('boilerplate.html', array('title' => 'Overview'));
?>
Attention, in the code shown above you of course have to pass a suitable title for every view. Otherwise all your pages have the title "Overview".
Views & Templates for Download
All views and the template of this chapter for downloading
Now you know the most important things about controllers and views. But it only gets really exciting when you can work with data! Therefore we will next look at the business objects!