Template Inheritance
Build multi-level layouts with extends, block/endblock, and parent().
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>© 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.