Layouts, elements and helpers
The header, menu and footer are the same on all pages. To avoid repeating them in every template CakePHP offers three tools: a layout is the common frame of a page, an element is a small reusable fragment, and a helper is an object that builds links and tags.
Layout
The layout is in templates/layout/default.php and already exists in the project. Simplify it to this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title><?= h($this->fetch('title')) ?></title>
</head>
<body>
<main>
<?= $this->fetch('content') ?>
</main>
</body>
</html>fetch('content') is the place where the action template is inserted. Open /articles: the "Articles" heading is now surrounded by this frame.
Page title
An action template passes values to the layout through blocks:
<div>
<?php $this->assign('title', 'All articles'); ?>
<h1>Articles</h1>
</div>assign() writes text into the title block and the layout outputs it with fetch('title'), so the browser tab shows "All articles".
Element
Elements are stored in the templates/element folder. Create the file templates/element/nav.php by hand:
<nav>
<?= $this->Html->link('Home', '/') ?>
<?= $this->Html->link('Articles', ['controller' => 'Articles', 'action' => 'index']) ?>
</nav>Include it in the layout above the main tag:
<body>
<?= $this->element('nav') ?>The menu appears on all pages. Data is passed to an element as the second argument: $this->element('card', ['article' => $article]).
The Html helper
Helpers are available in any template as $this->Name. Html builds links and includes files:
| Call | What it creates |
|---|---|
$this->Html->link('Text', ['action' => 'view', 5]) | A link by route |
$this->Html->image('logo.png', ['alt' => 'Logo']) | An image from webroot/img |
$this->Html->css('app') | A link to webroot/css/app.css |
$this->Html->script('app') | A link to webroot/js/app.js |
The helper escapes the link text itself, so h() is not needed there.
The Url helper
When only the address is needed, without a tag:
<form action="<?= $this->Url->build(['controller' => 'Articles', 'action' => 'index']) ?>">
<input type="search" name="q">
</form>build() returns /articles. The array is the same as in routes and in redirect().
Another layout
Create templates/layout/admin.php and choose it in an action:
$this->viewBuilder()->setLayout('admin');The page of this action is rendered inside the admin.php frame.
Common mistake
A link written as a string, <a href="/articles/view/5">, breaks when the route changes or the site moves to a subfolder. Build addresses with the Html->link() and Url->build() helpers: they take the address from routes and always give a working link.