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,
]);