Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Layout

A layout is the common frame of all pages: the html tag, the header, the menu, the footer. An action's view script contains only its own part, and Laminas inserts it into the layout. The header is then changed in one file instead of on every page.

Where the layout lives

In the skeleton the layout sits in the Application module: module/Application/view/layout/layout.phtml. Its name — layout/layout — is written in that module's configuration, in the view_manager section:

// module/Application/config/module.config.php
'view_manager' => [
    'template_map' => [
        'layout/layout' => __DIR__ . '/../view/layout/layout.phtml',
    ],
],

template_map is a table of "template name — file". By default Laminas takes the layout named layout/layout.

A simple layout

The skeleton's layout uses the Bootstrap library and is rather long. Replace its content with a short version:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <?= $this->headTitle('Blog')->setSeparator(' — ') ?>
    <?= $this->headLink()->prependStylesheet($this->basePath('css/style.css')) ?>
</head>
<body>
    <header>
        <a href="<?= $this->url('home') ?>">Home</a>
        <a href="<?= $this->url('blog') ?>">Posts</a>
    </header>
 
    <main><?= $this->content ?></main>
 
    <footer>A blog on Laminas</footer>
</body>
</html>

The key line is $this->content: the finished HTML of the action's view script goes here. It is not escaped. Open /blog — the list of posts sits between the header and the footer.

The window title

The headTitle() helper builds the title from parts. Add this line to the top of module/Blog/view/blog/post/index.phtml:

<!-- module/Blog/view/blog/post/index.phtml -->
<?php $this->headTitle('Posts'); ?>

The action's view script runs before the layout, so the browser tab shows "Posts — Blog".

Variables for the layout

An action passes data to the layout through the layout() helper:

public function indexAction()
{
    $this->layout()->setVariable('section', 'blog');
 
    return new ViewModel(['heading' => 'Posts']);
}

In the layout the value is available as $this->section — for example, to highlight the current menu item.

A different layout

For a section with a different design create a second file, for example module/Blog/view/layout/admin.phtml, and pick it in the action:

$this->layout('layout/admin');

The file is found through the template_path_stack of the Blog module.

No layout

Sometimes only a fragment of HTML is needed — for example, to load it with JavaScript. Then the layout is switched off:

$view = new ViewModel(['posts' => $posts]);
$view->setTerminal(true);
 
return $view;

The response contains only the action's view script.

Common mistake

If you delete the line <?= $this->content ?> from the layout, every page of the site looks the same: the header and footer are there, the content is not, and no error is shown. When editing the layout, make sure exactly one such line remains.

Thanks for reading!

Donate to the site — we work hard for you.