Views are where the HTML of your application goes. A view can be an entire web page
or just a small section of a page like a header, sidebar, navigation or footer.
Using views allows you to separate the presentation and business logic of your application.
Each view template is a .phtml file rendered by
the View object, which is accessible inside templates as
$this. The view system is convention-based: given a module, controller,
and action, the renderer resolves the template path automatically without requiring
any explicit registration.
The View Manager is configured in each module's module.config.php. It uses two mechanisms to locate templates:
template_map — explicitly maps a template name
to a file path. This is useful for global templates such as the layout and
the 404 error page.template_path_stack — points to a directory
containing all view templates. The renderer resolves templates inside this
directory using the convention
{module}/{controller}/{action}.phtml.Below is a typical module's View Manager configuration:
return [
'view_manager' => [
'template_map' => [
// Location of the layout template
'layout/layout' => 'layout/layout.phtml',
// Location of the 404 template
'error/404' => 'error/404.phtml',
],
// Where all the view files or templates are located
'template_path_stack' => __DIR__ . '/../view',
],
];
Your views must use the .phtml extension for them to get rendered by the template renderer. This is just a formality used to denote a file that is more HTML dense rather than PHP.
Please note that you have to follow the right structure on creating a template for View to render it properly.
Let's have an example below, we have a module Application and a controller of AboutController.php with a method of authorAction()
application_root/
module/
Application/ // Module
src/
Controller/
AboutController.php // Controller
view/
application/ // Module
about/ // Controller
author.phtml // Method
declare(strict_types=1);
namespace Application\Controller;
use JiNexus\Mvc\Controller\AbstractController;
use JiNexus\Mvc\Model\ViewModel;
class AboutController extends AbstractController
{
public function authorAction(): ViewModel
{
return new ViewModel();
}
}
The above example will have a view structure like this:
application_root/
module/
Application/ // Module
src/
view/
application/ // Module
about // Controller
author.phtml // Method
The framework resolves the template path automatically using this convention:
{module-lowercase}/{controller-without-controller-suffix-lowercase}/{action-without-action-suffix-kebab-case}.phtml
For the example above:
All views must be located in the module/{Module}/view directory. You can, of course, create subdirectories to better organize your view files.
When a controller action finishes, the application calls
dispatchAction(), which checks the action's return value. If the action
returns a ViewModel, its variables are merged into the View object via
setVariables(). You can also set variables directly on the View at any
time inside the action. There are three ways to pass data to the view:
declare(strict_types=1);
namespace Application\Controller;
use JiNexus\Mvc\Controller\AbstractController;
use JiNexus\Mvc\Model\ViewModel;
class IndexController extends AbstractController
{
public function indexAction(): ViewModel
{
// Pass variables to the view
return new ViewModel([
'foo' => 'Hello',
'bar' => 'World!',
]);
}
}
declare(strict_types=1);
namespace Application\Controller;
use JiNexus\Mvc\Controller\AbstractController;
class IndexController extends AbstractController
{
public function indexAction(): void
{
// Pass variables to the view
$this->view->set('foo', 'Hello');
$this->view->set('bar', 'World!');
}
}
declare(strict_types=1);
namespace Application\Controller;
use JiNexus\Mvc\Controller\AbstractController;
class IndexController extends AbstractController
{
public function indexAction(): void
{
// Pass variables to the view
$this->view->setVariables([
'foo' => 'Hello',
'bar' => 'World!',
]);
}
}
Inside a .phtml template, $this refers to the
View object. Each variable passed by the controller is stored
internally in two forms — a safe (HTML-encoded) copy and an
unsafe (raw) copy. Accessing a variable via $this->foo
uses the magic __get() method, which calls
get('foo', true) and returns the HTML-encoded value by default.
This protects your output from XSS without requiring manual escaping.
If you need the raw, unescaped value, use get() with the second
argument set to false:
<?php echo $this->get('foo', false); // raw, no HTML encoding
Here is a complete example:
<div>
<p><?php echo $this->foo . ' ' . $this->bar; ?></p>
</div>
With the variables set earlier, the output will be:
Hello World!
These are the list of available view methods that can be used in templates.
| Method | Description |
|---|---|
basePath() |
Get the base path of the application |
baseUrl() |
Get the base URL of the application |
content() |
Render content of the module, controller and method from the matched route |
htmlEncode() |
Recursively make a value safe for HTML |
htmlDecode() |
Recursively decode an HTML-encoded value |
get($key, $htmlEncode = true) |
Get a view variable (HTML-encoded by default) |
set($key, $value = null) |
Set a view variable |
setVariables(array $variables = []) |
Set all view variables at once |
getVariables() |
Get all view variables |
render(string $file = '') |
Render a template file |
url(string $routeName) |
Get a URL from a named route |
content()The layout template is the outer shell shared by every page. It typically
calls $this->content() to render the matched controller action's
view template in the page body:
<!DOCTYPE html>
<html>
<head>
<title><?php echo $this->title; ?></title>
</head>
<body>
<?php echo $this->content(); ?>
</body>
</html>
The content() method renders the template resolved from the
matched route — in our example, application/about/author.phtml —
and outputs its content directly at that point in the layout.
If you found a typo or error, please help us improve this document. Create Issue