Views & Layouts
Once a controller action finishes its work, CakePHP hands off to the view layer to
turn that data into HTML. Views are plain .php template files that live in predictable
locations, and a layout wraps every view in the shared page furniture — header,
navigation, footer — so you don't repeat that markup on every page.
Where View Files Live
Following the same convention-over-configuration idea from the previous pages, CakePHP looks for a view template at a path built from the controller and action name:
| Controller / Action | Template file CakePHP looks for |
|---|---|
ArticlesController::index() | templates/Articles/index.php |
ArticlesController::view() | templates/Articles/view.php |
UsersController::login() | templates/Users/login.php |
So the index() action on ArticlesController (the one we set up in
Controllers) automatically renders
templates/Articles/index.php — there's no line of code anywhere that says "render this
file"; the folder and file name are the wiring.
Getting Data Into the View
A controller action makes data available to its view with $this->set(). Whatever
you pass becomes a plain, directly-usable variable inside the template — no extra unpacking needed.
<?php
namespace App\Controller;
class ArticlesController extends AppController
{
public function index()
{
$articles = $this->Articles->find()->all();
$this->set('articles', $articles);
}
}
Because of that set('articles', $articles) call, the view file at
templates/Articles/index.php can simply refer to $articles directly, as
shown in the worked example below.
Worked Example: A Simple Index View
Here is a realistic templates/Articles/index.php that loops over the
$articles variable set by the controller above and renders a list of titles.
<h1>Articles</h1>
<ul>
<?php foreach ($articles as $article): ?>
<li>
<?= h($article->title) ?>
</li>
<?php endforeach; ?>
</ul>
h() is CakePHP's shortcut for htmlspecialchars() — always wrap
user-supplied data with it before printing to avoid XSS, the same concern covered on Core PHP's
Security page.Layouts: The Shared Page Wrapper
A layout is the outer HTML that surrounds every view — the <html>,
<head>, navigation, and footer markup you don't want to retype in each template.
By default CakePHP wraps every rendered view in templates/layout/default.php. Inside
that file, one line marks the spot where the current view's own content gets inserted:
<!DOCTYPE html>
<html>
<head>
<title>My Site</title>
</head>
<body>
<?= $this->fetch('content') ?>
</body>
</html>
Every time templates/Articles/index.php (or any other view) renders, its output is
captured and dropped into that $this->fetch('content') spot inside the layout — you
never have to include the layout manually.
View Blocks: Targeting Specific Layout Regions
Sometimes a single view needs to inject content into a part of the layout other than the
main content area — a page-specific <title>, or an extra CSS/JS file only that
page needs. CakePHP calls these named regions blocks. A view starts a block, writes
into it, and ends it; the layout later fetches that named block wherever it needs it.
<?php $this->start('scripts'); ?>
<script src="/js/articles.js"></script>
<?php $this->end(); ?>
Then, wherever the layout wants that content printed — typically just before </body>
— it fetches the block by name:
<?= $this->fetch('scripts') ?>
This keeps page-specific scripts and styles defined right inside the view they belong to, while still letting the layout decide exactly where they end up on the page.
$this->Articles
fetches records from the database in the first place.