Views & Templates
TrueFramework's view engine is plain PHP. Templates are .phtml files with a small metadata block at the top, wrapped at render time in a layout you control.
Render a template
$App->view->render('contact.phtml', [
'firstName' => $firstName,
'errors' => $errors,
]);
The variables array is unpacked into the template's local scope — inside contact.phtml you'll see $firstName and $errors directly.
Template metadata
Anything between the start of the file and a {endmeta} marker is parsed as INI-style metadata, not template body:
title = "Contact Us"
description = "Get in touch with our team."
canonical = "https://example.com/contact"
modified = "2026-04-30"
css = "/assets/css/contact.css"
js = "/assets/js/contact.js"
{endmeta}
<h1>Contact</h1>
Anything declared here is available on $App->view inside the layout — $App->view->title, $App->view->description, etc.
Layouts
The layout wraps every rendered view. Set it once in your bootstrap or per-request:
$App->view->layout = BP.'/app/views/_layouts/base.phtml';
A typical layout pulls metadata from $App->view and yields the rendered body via $App->view->bodyHtml (the variable name depends on your template — the renderer sets it for you):
<!doctype html>
<html>
<head>
<title><?=esc($App->view->title ?? '')?></title>
<meta name="description" content="<?=esc($App->view->description ?? '')?>">
<?= $App->view->headHtml ?? '' ?>
</head>
<body>
<?= $App->view->bodyHtml ?>
</body>
</html>
Asset hooks
Multiple comma-separated paths can be assigned to a single declaration. The layout iterates them and emits <link> / <script> tags:
// In a controller, before render()
$App->view->css = '/assets/css/page.css';
$App->view->js = '/assets/js/page.js, /assets/js/extra.js';
// Append more without overwriting
$App->view->js = '/assets/js/analytics.js';
Inline blocks
The metadata header supports a few special blocks for one-off page-level injection:
{head}
<meta property="og:type" content="article">
{/head}
{style}
.callout { color: red }
{/style}
{script}
console.log('loaded');
{/script}
{jsonld}
{"@context":"https://schema.org","@type":"Article"}
{/jsonld}
{endmeta}
Globals
Pass values you want available to every view through $App->view->variables:
$App->view->variables = [
'siteName' => 'Acme',
'year' => (int) date('Y'),
];
Configuration
Override defaults at construction time:
$App->view = new \True\PhpView([
'base_path' => BP.'/app/views/',
'assets_path' => '/assets/',
'layout' => BP.'/app/views/_layouts/base.phtml',
'404' => '404-error.phtml',
'cache' => false,
]);