Nate's template inheritance system works similarly to Twig, allowing you to define a base layout with replaceable blocks, and then extend it in child templates.

Defining a Base Layout

Use $this->block('name') and $this->endblock() to define blocks that child templates can override:

<!-- base.tpl.php -->
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title><?php $this->block('title') ?>My Site<?php $this->endblock() ?></title>
</head>
<body>
    <header>
        <h1>My Site</h1>
    </header>

    <main>
        <?php $this->block('content') ?>
            <p>Default content goes here.</p>
        <?php $this->endblock() ?>
    </main>

    <footer>
        <p>&copy; 2026 My Site</p>
    </footer>
</body>
</html>

Extending a Layout

Use $this->extends('path') at the top of a child template to inherit from a parent. Then override any blocks:

<!-- page.tpl.php -->
<?php $this->extends('base.tpl.php') ?>

<?php $this->block('title') ?>About Us<?php $this->endblock() ?>

<?php $this->block('content') ?>
    <h2>About Our Company</h2>
    <p>We build awesome software with PHP.</p>
<?php $this->endblock() ?>

Multi-Level Inheritance

Nate supports multiple levels of inheritance. For example, a chain of three templates:

<!-- base.tpl.php -->
<?php $this->block('content') ?>
    <p>Default content</p>
<?php $this->endblock() ?>
<!-- layout.tpl.php -->
<?php $this->extends('base.tpl.php') ?>

<?php $this->block('content') ?>
    <div class="layout">
        <?= $this->parent() ?>
    </div>
<?php $this->endblock() ?>
<!-- page.tpl.php -->
<?php $this->extends('layout.tpl.php') ?>

<?php $this->block('content') ?>
    <article>
        <h1><?= $this->title ?></h1>
        <p><?= $this->body ?></p>
    </article>
<?php $this->endblock() ?>

Using parent()

The $this->parent() function returns a placeholder string that gets replaced with the parent block's content during compilation. This is useful when you want to append to a block rather than completely override it:

<?php $this->block('title') ?><?= $this->parent() ?> | Subpage<?php $this->endblock() ?>

If the parent block contained "My Site", this would render as "My Site | Subpage".

How it works: parent() is not a real function call at runtime. It returns the literal string <_parent/>, which the Compiler replaces with the actual parent content during its final pass. This means you can only use it inside a block() / endblock() pair.

Including Partial Templates

Use includeTemplate() to render reusable template partials with their own data:

<!-- page.tpl.php -->
<?php $this->extends('base.tpl.php') ?>

<?php $this->block('content') ?>
    <h2>User List</h2>
    <table>
        <tr>
            <th>Name</th>
            <th>Email</th>
        </tr>
        <?php foreach ($this->users as $user) : ?>
            <?= $this->includeTemplate('includes/row.tpl.php', [
                'name'  => $user['name'],
                'email' => $user['email'],
            ]) ?>
        <?php endforeach ?>
    </table>
<?php $this->endblock() ?>
<!-- includes/row.tpl.php -->
<tr>
    <td><?= $this->name ?></td>
    <td><?= $this->email ?></td>
</tr>

Tip: Paths in includeTemplate() are resolved relative to the current template file's directory, making it easy to organize partials in subdirectories.

Empty Blocks

You can define a block without default content, forcing child templates to provide it:

<?php $this->block('sidebar') ?><?php $this->endblock() ?>

If a child template does not override this block, it will simply output nothing — no default content is rendered.