ViewFish PHP Templating Engine
Nested Templates
You can include templates within templates using the syntax:
{{@template file=template_name}}
Where template_name is the filename of the template (e.g., sidebar.tmpl). Templates can be nested recursively — a nested template can include its own nested templates.
Basic Usage
<!-- main.tmpl -->
<div class="page">
<h1>{{title}}</h1>
{{@template file=sidebar.tmpl}}
<div class="content">{{body}}</div>
</div>
$t = new ViewFish\viewfish();
$t->set_template_path('/path/to/templates/');
$template = $t->load_template('main.tmpl');
echo $t->render($template, [
'title' => 'My Page',
'body' => 'Hello world',
'menu' => 'Home | About | Contact', // available to sidebar.tmpl too
]);
Data Scoping
Nested templates inherit the outer template's data by default. All variables from your $data array are available in nested templates.
To override specific values for a nested template, create a sub-array keyed by the template name:
$data = [
'x' => 'shared value',
'y' => 'outer value',
'sidebar' => [
'y' => 'sidebar-specific value', // overrides 'y' for sidebar.tmpl
],
];
Nesting Hierarchy
main.tmpl
├── header.tmpl
├── content.tmpl
│ └── widget.tmpl
└── footer.tmpl
$data = [
'site_name' => 'My Site', // available everywhere
'year' => '2025', // available everywhere
'content' => [
'title' => 'Article Title', // overrides for content.tmpl and its children
'widget' => [
'color' => 'blue', // overrides for widget.tmpl only
],
],
];
Each nested template receives the parent's data merged with any template-specific overrides. Child templates (like widget.tmpl inside content.tmpl) inherit from their parent's scope.
Recursion Limit
ViewFish limits nesting to 10 levels deep to prevent infinite recursion. If a template includes itself (directly or indirectly), rendering will stop at the depth limit and return the template as-is.
You can see this in action in Example 4.