Views
Views are Latte templates. A page's view property determines which template renders it and which controller, router, and field definitions apply.
View selection
PhlatPage looks for a Latte template matching the page's view property (defaults to default), preferring site/ over phlat/:
site/views/{view}.latte ← checked first
phlat/views/{view}.latte ← fallback
If no matching template is found, a NotFoundException is thrown.
Template variables
Every view receives $page and $app automatically, plus anything returned by controllers. The framework app controller also provides $styles, $scripts, and $logo.
{$page->title}
{$page->url()}
{$app->config->get('site_name')}
Layout inheritance
Use Latte's {layout} and {block} tags to share a common outer shell:
{* site/views/post.latte *}
{layout 'site/root.latte'}
{block body}
<article>
<h1>{$page->title}</h1>
<div class="prose">{$page->body|render}</div>
</article>
{/block}
The layout file defines the outer HTML and declares named blocks:
{* site/views/site/root.latte *}
<!DOCTYPE html>
<html>
<head>
<title>{$page->title}</title>
<link rel="stylesheet" href="{$styles}">
</head>
<body>
{block body}{/block}
</body>
</html>
Latte syntax essentials
Assign without output using {var}. {$x = ...} assigns and outputs.
{var $children = $page->children()}
{foreach $children as $child}
<a href="{$child->url()}">{$child->title}</a>
{/foreach}
{if !$page->summary->empty()}
<p>{$page->summary}</p>
{/if}
The |render filter
|render passes a field through its type's render template. For plain fields it HTML-escapes. For typed fields (markdown, code, image) it renders through the field's view template:
{$page->title} {* escaped string output *}
{$page->body|render} {* markdown → HTML, code → highlighted block *}
Always check before rendering optional fields:
{if !$page->body->empty()}
<div class="prose">{$page->body|render}</div>
{/if}
Icons
{icon()} renders an inline SVG from phlat/icons/ by name:
{icon('check')}
{icon('arrow-right', 'w-4 h-4 text-primary')}
The second argument sets the class attribute on the <svg> element.
Partials
{include} pulls in a partial. Paths resolve from the views root:
{include 'site/logo.latte'}
{include 'ui/theme-picker.latte', options: ['default', 'dark', 'dim']}
Variables after the comma are passed to the partial as locals.
<?php
// site/views/article.latte — shown as PHP for code highlighting.
// Actual file is Latte syntax:
//
// {layout 'site/root.latte'}
//
// {block body}
// <article class="prose">
// {include 'site/title.latte'}
//
// {if !$page->cover->empty()}
// <img src="{$page->cover->url()}" alt="">
// {/if}
//
// {$page->body|render}
// </article>
// {/block}