Layouts provide a frame for your pages, containing all the common elements shared by most, if not all, of your templates.

The intended purpose of layouts is to avoid unnecessary repetition: instead of each view script including a header.php, footer.php, and whatever other files they may require, a layout contains all those shared elements and the contents of the view script are then injected into the layout.

Example layout file

Here's an example of what a layout file might look like (/site/templates/views/layouts/default.php):

<!doctype html>
<html lang="<?= $this->lang ?>">
        <!-- metadata -->
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta name="generator" content="ProcessWire CMS/CMF">
        <?php if ($page->meta_description): ?>
            <meta name="description" content="<?= $page->meta_description ?>">
        <?php endif; ?>
        <?php if ($page->meta_keywords): ?>
            <meta name="keywords" content="<?= $page->meta_keywords ?>">
        <?php endif; ?>
        <!-- page title -->
        <title><?= $page->title ?></title>
        <!-- stylesheets -->
        <link rel="stylesheet" href="<?= $config->urls->static ?>css/main.css">
    <body class="template-<?= $page->template ?>">
        <header class="header">
            <h1 itemprop="headline"><?= $page->get('headline|title') ?></h1>
            <?php include $partials->menu->top ?>
            <?php include $partials->menu->breadcrumbs ?>
            <div id="content"><?= $placeholders->default ?></div>
        <footer class="footer">
            <div class="footer__column"><?= $home->footer_1 ?></div>
            <div class="footer__column"><?= $home->footer_2 ?></div>
        <script src="<?= $config->urls->static ?>js/main.js"></script>

What's important here is that the layout file is basically just regular HTML/PHP file, with access to ProcessWire's API and any data you've passed to wireframe when first initiating it (in this example the $this->lang attribute), as well as any additional data that you've passed from a Controller file to View.

The content itself is injected into $placeholders->default through the use of view placeholders.

Back to top