Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

View scripts

A view script is a file with HTML and PHP inserts that turns data into a page. View scripts have the .phtml extension and live in the module's view folder. A controller action passes data to the view script through a ViewModel object.

Where view scripts are looked up

First tell Laminas that the module has a folder with view scripts. Add a section to module/Blog/config/module.config.php:

// module/Blog/config/module.config.php
'view_manager' => [
    'template_path_stack' => [
        __DIR__ . '/../view',
    ],
],

template_path_stack is the list of folders where the framework looks for view scripts. Here it is module/Blog/view.

The file name

The path to a view script is made of three lowercase names: the module, the controller without the word Controller, and the action.

ActionView script file
PostController::indexAction()module/Blog/view/blog/post/index.phtml
PostController::viewAction()module/Blog/view/blog/post/view.phtml
PostController::addAction()module/Blog/view/blog/post/add.phtml

The first view script

Change the action so that it returns a ViewModel:

// module/Blog/src/Controller/PostController.php
use Laminas\View\Model\ViewModel;
 
public function indexAction()
{
    return new ViewModel([
        'heading' => 'Posts',
    ]);
}

Create the folders module/Blog/view/blog/post and the file index.phtml:

<!-- module/Blog/view/blog/post/index.phtml -->
<h1><?= $this->escapeHtml($this->heading) ?></h1>

The array key heading became the property $this->heading in the view script. Open /blog: the heading "Posts" appears inside the site's common frame with the header.

A list in a view script

Pass an array of posts to the view script:

return new ViewModel([
    'heading' => 'Posts',
    'posts' => [
        ['id' => 1, 'title' => 'First post'],
        ['id' => 2, 'title' => 'Second post'],
    ],
]);

View scripts use the colon syntax for loops and conditions — it reads better among HTML:

<!-- module/Blog/view/blog/post/index.phtml -->
<h1><?= $this->escapeHtml($this->heading) ?></h1>
 
<?php if (count($this->posts) === 0): ?>
    <p>No posts yet.</p>
<?php endif; ?>
 
<ul>
    <?php foreach ($this->posts as $post): ?>
        <li><?= $this->escapeHtml($post['title']) ?></li>
    <?php endforeach; ?>
</ul>

The page shows a list of two titles.

Escaping

Escaping replaces characters such as < with safe codes, so that text from the database or a form does not turn into HTML tags.

HelperWhere to use it
escapeHtml($text)Text between tags
escapeHtmlAttr($value)An attribute value: title, alt, value
escapeJs($value)A value inside JavaScript
escapeUrl($value)A part of an address in a link

A different view script

If an action needs a view script with another name, set it explicitly: $view = new ViewModel(); $view->setTemplate('blog/post/list');. The name is written without the extension and without the view folder.

Common mistake

Writing <?= $this->heading ?> without escapeHtml() outputs the value as is: a <script> tag from a post title runs in the visitor's browser. Laminas does not escape output for you — wrap every value that came from a user or the database in escapeHtml().

Thanks for reading!

Donate to the site — we work hard for you.