-
Notifications
You must be signed in to change notification settings - Fork 16
Handling placeholders
Consider the common situation where you have to manage and show data dynamically on the web pages. You just learned that showing output is the main role of the View. This is still valid also when data to show are dynamical. For this purpose, in this paragraph, we expose a solution for handling dynamic web page by a using static Template, View, and Controller
Suppose we have the following templates\home.html.tpl
, the file just is shown on the previous page, in which we have placed the static placeholder {UserName}. Now we want to assign to it a value, eg. 'Mark' but the assignment must be dynamically provided at run-time.
<!DOCTYPE html>
<html>
<head>
<title>Site home page</title>
</head>
<body>
<p>Welcome to the site Home Page</p>
<br />
<p>Welcome {UserName}</p>
</body>
</html>
To do this job we procede by creating the foolowing View class we call views\Home.php
, whitch exetends framework\View
:
<?php
namespace views;
use framework\View;
class Home extends View
{
/* Contructor.
* Override framework\View __construct() to
* use templates\home.html.tpl
*/
public function __construct($tplName = null)
{
$tplName = "home";
parent::__construct($tplName);
}
/* Custom method designed to manage the dynamic content
* of the placeholder {UserName}.
*
* @param string $name The name value to assign to {UserName}
*/
public function setUserName($name)
{
// setVar is a method inherited from framework\View
$this->setVar("UserName",$name);
}
}
We are using the method setVar()
provided by framework\View to replace a value to placeholder {UserName}
.
Note that, unlike the instance of the abstract framework\View
we used to show the static content in the previous example, we are now creating a class, views\Home.php
, that extends framework\View
. The reasons we make so are:
-
Unlike a template that cloth with a static behavior, one containing placeholders or even blocks, assumes a dynamic and specialized behavior. Consequently, it is better to manage it by creating a custom View and by using its isìnstance. In fact, a custom View can be appositely written for the treatment of the dynamism to be realized by consuming the Placeholders and Blocks of a user Template. The framework\View contains only abstract behavior that can be specialized on custom actions
-
By implementing the (specializing)
setUserName($name)
using an external class, we are respecting the SOC principle. The views\Home class should be the only entity enabled to manage a custom Template equipped with specialized placeholders (or blocks) necessary for generating dynamic content. -
To avoid calling the
framework\View->setVar()
method directly from within thecontrollers\Home
. The setVar method is a View responsibility.
Then, we modify the controller controllers\Home.php as follow to enable it to communicate with views\Home.php
(pay attention to the comments):
namespace controllers;
use framework\Controller;
use views\Home as HomeView;
class Home extends Controller
{
/**
* Home constructor.
* @override framework\Controller __construct()
*/
public function __construct()
{
/**
* A reference to the file: templates/home.html.tpl
* @note Do not to specify the file extension ".html.tpl".
*/
$tplName = "home";
/**
* Set the view with a new object of type framework\View.
* @note: We create the HomeView object by using the
* template reference.
*/
$this->view = new HomeView($tplName);
/**
* To starting up the standard WebMVC behavior of acting
* cooperation between Controller and the View just
* invoke the parent constructor by passing the current view
*/
parent::__construct($this->view);
/**
* By default, the controller behavior will be
* that to greet a Guest user
*/
$this->view->setUserName("Guest");
}
/**
* Specifies the user for greeting
* It wraps a call to $view->setUserName($name)
*
* @param string $user User name value to be greet
*/
public function userToGreet($user) {
$this->view->setUserName($user);
$this->render();
}
}
The following figure shows the WebMVC directory tree with files location:
Note we used 'Home' name for naming Controller, View, and 'home' for Template. We talked about this on the naming convention page page.
Finally, run the controller by typing the following address into your web browser:
http://localhost/home/user_to_greet/Mark
You should see the page:
You can also run the controller without calling its userToGreet()
method. Type:
http://localhost/home/
Now, you should see:
Although this example is very simple, there are still many feasible considerations to do:
The method setVar($placeholder, $value)
provided by framework\View find a given placeholder in the active template and replace it with a given value.
Bear in mind that:
- If many occurrences of placeholders (like {UsenName}) are designed in a template, then they will be all replaced in one single setVar() call.
- You must call a
setVar()
method after the view has been initialized in the controller. - You must not call twice the setVar() method by giving it, each time, the same placeholder.This because after the first time the placeholder will be replaced with a value, then, at the second call of setVar(), no placeholder will be found and an exception will be thrown.
- It provides some useful actions. Follow the method reference extracted from
framework\View
source code:
/**
* Replaces all occurrences of the given placeholder with a given value.
* If the placeholder is contained into a (previously opened) block
* the replacement is made against the opened block.
*
* You can also specify if the given placeholder is enclosed in braces,
* if you need to purify the given value against XSS and CHARSET for the given value
*
* @param string $placeholder The placeholder to find
* @param string $value The value for replacing to founded placeholder
* @param bool|true $useBraces If true (default) the placeholder name contain braces {}
* @param bool $xssPurify If true (default=false) purify the value against XSS
* @param string $charset Charset string for the give value. Default (UTF8) is the CHARSET
* constant value defined into config\application.config.php
*
* @throws VariableNotFoundException. If variable/placeholder was not found
* @throws NotInitializedViewException If template was not loaded
*/
public function setVar($placeholder, $value, $useBraces=true, $xssPurify=false, $charset = CHARSET)
Although you can invoke the render()
method from the Controller, in action this is a service implemented by the View for showing the GUI to the screen.
When you are writing a public method of a Controller, you need to manually invoke method render()
anytime you want to output the GUI to the screen. Differently, you will not need to invoke it when you are writing a Controller constructor. The reason is that WebMVC, by default, when you are invoking a Controller without calling any of its methods, automatically executes render()
for you. See the previous controller\Home
source and you will find that we invoke render()
inside userToGreet()
but never in __construct()
;
In the next page, we will introduce the dynamic Blocks handling for generating dynamic pages containing repeated sections