Template Inheritance

Learn how Tplix template inheritance works — extend a base layout and override only the blocks that change. Cleaner than includes, scales to any project size, with full code examples.

Template Inheritance

Template inheritance brings object-oriented thinking to your templates. Instead of stitching pages together with {include} tags, you extend a base layout and override only the blocks that change — just like extending a class and overriding its methods.

🧱
Base Layout = Base Class

Defines the overall structure and default content for every page that extends it.

🔲
Blocks = Methods

Named regions inside the layout that child templates can override — or leave as-is to use the default.

📄
Child Template = Subclass

Extends the layout and only defines what's different — inheriting everything else automatically.

The Challenge

Imagine you're building an HTML page that needs custom CSS and JavaScript files loaded inside the <head> tag. The problem: the <head> is defined in a shared header template that was already included at the top of the page. Without inheritance, solutions get messy fast.

Template inheritance solves this elegantly. Let's first look at the old way — using {include} tags — then see how inheritance replaces it.

✕

Without Inheritance — the old way

header.tpl
<html> <head> <title>{$title|default:"Default Page Title"}</title> </head> <body>
footer.tpl
</body> </html>
mypage.tpl
{include file="header.tpl" title="My Page Title"} My HTML Page Body goes here {include file="footer.tpl"}
Output — mypage.tpl
<html> <head> <title>My Page Title</title> </head> <body> My HTML Page Body goes here </body> </html>
Problems with this approach
  • Layout is split across multiple files — hard to get a complete picture of a page
  • Injecting custom CSS or JS into <head> from a child page requires messy workarounds
  • Every page template must manually remember to include header and footer
✓

With Template Inheritance — the clean way

layout.tpl — base layout
<html> <head> <title>{block name=title}Default Page Title{/block}</title> </head> <body> {block name=body}{/block} </body> </html>
mypage.tpl — child template
{extends file="layout.tpl"} {block name=title}My Page Title{/block} {block name=body}My HTML Page Body goes here{/block}
Output — mypage.tpl
<html> <head> <title>My Page Title</title> </head> <body> My HTML Page Body goes here </body> </html>
Why this is better
  • The entire page structure lives in one file — layout.tpl — not scattered across header/footer fragments
  • Child templates only define what's different — everything else is inherited automatically
  • Any number of child templates can chain together — unlimited inheritance depth

Solving the Original Challenge

Remember the problem: injecting page-specific CSS and JavaScript into the <head> from a child page. With inheritance, just add a new {block} to the layout — then override it in the child template. No hacks required.

layout.tpl — updated with a {block name=head} slot
<html> <head> <title>{block name=title}Default Page Title{/block}</title> {block name=head}{/block} <!-- empty by default, child can fill this --> </head> <body> {block name=body}{/block} </body> </html>
mypage.tpl — child template injecting CSS + JS into <head>
{extends file="layout.tpl"} {block name=title}My Page Title{/block} {block name=head} <link href="/css/mypage.css" rel="stylesheet" type="text/css"/> <script src="/js/mypage.js"></script> {/block} {block name=body}My HTML Page Body goes here{/block}
Output — mypage.tpl
<html> <head> <title>My Page Title</title> <link href="/css/mypage.css" rel="stylesheet" type="text/css"/> <script src="/js/mypage.js"></script> </head> <body> My HTML Page Body goes here </body> </html>

How the blocks flow

layout.tpl
<html>
<head>
{block name=title}…{/block}
{block name=head}{/block}
</head>
<body>
{block name=body}{/block}
</body>
</html>
mypage.tpl
{extends file="layout.tpl"}
{block name=title}
  My Page Title
{/block}
{block name=head}
  <link href="/css/mypage.css"…>
  <script src="/js/mypage.js">
{/block}
{block name=body}
  Page content here
{/block}

Blocks defined in the child override the matching blocks in the layout. Blocks not overridden keep their default content.

One layout file rules them all

Change the base layout once and every child template reflects it automatically. No hunting through dozens of header/footer files.

Child templates stay minimal

Each page only defines what makes it unique. The inherited structure never needs to be repeated — keeping templates clean and DRY.

Blocks can be empty by default

An empty {block} in the layout is a placeholder — child templates fill it in only when needed, like the head block for custom assets.

Chains of inheritance

Child templates can be extended by further children — creating deep chains like layout → section → page for large sites.

Ready to simplify your templates?

Read the full inheritance reference in the documentation to see all block options and chaining examples.

View Full Docs →