Search by

tereta / theme

tereta

Template engine for PHP 8.2+: a fluent view builder that renders .phtml templates with meta and data, and resolves nested includes relative to the theme root.

0.0.5 2026-10-10 17:28 UTC

This package is not auto-updated.

Last update: 2026-10-10 14:28:47 UTC


README

๐ŸŒ English | ะ ัƒััะบะธะน | ะฃะบั€ะฐั—ะฝััŒะบะฐ

Template engine for PHP. It renders .phtml templates from a theme folder and lets one template include another.

Requirements

PHP 8.2+, psr/container ^2.0.

Installation

composer require tereta/theme

Quick start

A theme is a folder with .phtml templates:

themes/base/
โ”œโ”€โ”€ page/
โ”‚   โ””โ”€โ”€ product.phtml
โ””โ”€โ”€ blocks/
    โ””โ”€โ”€ footer.phtml

Render a template by its name inside the theme, without .phtml:

use Tereta\Theme\View;

$view = new View('/path/to/themes/base');

$html = $view->builder()
    ->setTemplate('page/product')
    ->setMeta(['lang' => 'en'])
    ->setData(['title' => 'Hello'])
    ->render();

Inside a template

Each value from setData() becomes a variable with the same name. Meta values are available in $meta. Print every value through $escape:

<!-- page/product.phtml -->
<html lang="<?= $escape($meta['lang']) ?>">
<h1><?= $escape($title) ?></h1>

All data is also available as one array in $data.

Safe output

The template engine does not escape values by itself: <?= $title ?> prints the value exactly as it is. So print every value with $escape, even if it looks safe now - a title or a name can come from a user or from the database later.

$escape turns the special HTML characters, quotes too, into safe text, so it works both in text and in attribute values:

<h1><?= $escape($title) ?></h1>
<input name="title" value="<?= $escape($title) ?>">

If $title is <b>Tom & Jerry</b>, the page shows exactly this text and not bold text.

Print a value without $escape only when it is HTML that you have made yourself and trust, for example the result of another render(). Mark such a place with a comment, so it is clear that it is not a mistake:

<?= $content /* trusted HTML from render() */ ?>

$escape does not check links: an address like javascript:... still works after escaping. Check the addresses of links that come from users before you print them.

$escape accepts a string, a number or null.

Include one template into another

Use $include with a template name from the theme folder:

<?php $include('blocks/footer') ?>

The name is always counted from the theme folder, not from the current template. A template can not be included from outside the theme folder, for example with ../. The included template gets the same $meta and data.

The second parameter passes an extra value, it is available in $attribute:

<!-- page/product.phtml -->
<?php $include('blocks/menu', $meta['menu']) ?>

<!-- blocks/menu.phtml -->
<?php foreach ($attribute as $item) : ?>
    <a href="<?= $escape($item['url']) ?>"><?= $escape($item['label']) ?></a>
<?php endforeach ?>

The names meta, data, include, escape, attribute, template and variables are reserved. Data keys with these names do not become variables, but they are still in $data.

Theme settings

Tereta\Theme\Context\Config stores theme settings, for example the themes folder and the current theme:

use Tereta\Theme\Context\Config;

$config = (new Config())
    ->set('path', '/path/to/themes')
    ->set('theme', 'base');

$view = new View($config->get('path') . '/' . $config->get('theme'));

has() checks whether a setting exists.

Errors

  • Tereta\Theme\Exceptions\Template - the template or the theme folder is not found, or the template is outside the theme folder.
  • Tereta\Theme\Exceptions\NotFound - the setting is not found in Config.