PHP Luminova: Smarty Template Engine Extension
Render templates efficiently with Luminova’s Smarty extension helpers that reduce unnecessary class loading and keep your application fast and easy to maintain.
Luminova Smarty template extension helps you use the Smarty template engine smoothly inside your Luminova application. Luminova adds a few built-in helpers such as static, new, fn, and const. These helpers make your templates faster, reduce repeated class initialization, and cut down on long-term maintenance work.
The goal is simple: make Smarty easy to use in Luminova so you can focus on building your application, not fighting your tools.
Note:
Luminova Smarty uses
{{and}}as its default delimiters, and Auto Literal is disabled.This keeps the syntax consistent with Twig Template and allows clean spacing inside delimiters, and prevents Smarty from interpreting single curly braces as template tags (e.g., it requires
{{ foo }}, not{foo}).
Smarty Support
Luminova’s Smarty extension works with Smarty Version: 5.7, if you use a newer version and your application begins to break, downgrade back to version 5.7.For full Smarty documentation, see the official website: https://smarty-php.github.io/smarty
Install Smarty with Composer:
composer require "smarty/smarty"Template Context Object
In Luminova Smarty, the template context is exposed through a single $self object.This works much like Luminova’s default PHP template system, where your view options and the view object itself are isolated and accessed through $self.
So anything you pass from your controller—plus default view options, can be reached using $self->property or $self.method().
Example:
namespace App\Controllers\Http;
use Luminova\Base\Controller;
class MainController extends Controller
{
public function index(): int
{
return $this->view('index', [
'name' => 'Peter',
'age' => 34
]);
}
}Accessing passed options in the template
{{ $self.name }}
{{ $self.age }}Default options always available
{{ $self.title }}
{{ $self.asset }}
{{ $self.href }}Accessing the view object
{{ $self->getOptions() }}
{{ $self->getOption('title') }}
{{ $self.app.session->isOnline() }}Deep Object Chaining
In standard Smarty, you cannot freely chain through nested objects unless you first assign each level to its own Smarty variable. For example, accessing the session username normally requires multiple assignments:
{{ $self.app assign='app' }}
{{ $app.session assign='session' }}
{{ $session->get('username') }}Luminova’s Smarty Proxy removes this limitation.You can access deep objects and call their methods directly, without assigning anything:
{{ $self.app.session->get('username') }}In regular Smarty, this direct chaining is not possible, you must assign each object to a variable before you can reach the next level.
Note:Deep object chaining only works with public properties and methods on the
App\Applicationclass, Exported classes, template options, and theLuminova\Template\Viewobject.External classes registered as globals, or standard Smarty plugins do not use the Luminova template proxy, so they will not support this extended chaining behavior.
Exporting Properties and Classes
If you still use the older “export to view” style, you can expose any class to all templates through the application boot process.
namespace App;
use App\Utils\Example;
use App\Utils\StaticExample;
use Luminova\Foundation\Core\Application as CoreApplication;
class Application extends CoreApplication
{
protected function onCreate(): void
{
$this->view->export(Example::class, 'example');
$this->view->export(StaticExample::class);
}
}Accessing exported classes in Smarty templates
{{ $self.example->getValue() }}
{{ $self.StaticExample::getValue() }}Calling Static Classes
In Luminova Smarty, you can call static methods in two ways:
Register the class inside
App\Config\Templates\Smarty\Extensions→registerClasses().This lets you call it using an alias.Call it directly using the
statichelper with the full namespace.This does not require registration, avoids unnecessary class initialization, and is usually the leaner choice.
The helper follows this signature:
function static(string $class, string $member, mixed ...$arguments): mixedParameters
| Parameter | Type | Description |
|---|---|---|
$class | string | Fully qualified class name or registered alias. |
$member | string | The static property or method name to call. |
$arguments | mixed | Optional method arguments. |
Note
static()is not a real PHP function.It only exists inside Smarty templates. You cannot call it in PHP code.
Examples:
Calling a registered class (from registerClasses in/app/Config/Templates/Smarty/Extensions.php)**
{{ static('Example', 'getName') }}Set a value and assign it
{{ static('Example', 'setName', 'Peter') assign='example' }}
{{ $example->getName() }}Call a static method directly using the full namespace
{{ static('App\\Utils\\Example', 'getName') }}{{ static('\\App\\Utils\\Example' 'setName', 'names') assign = 'example' }}
{{ $example->getName() }}Instantiate a Class Object
In Luminova Smarty, you can create a new class instance inside a template in two ways:
Register the class inside
App\Config\Templates\Smarty\Extensions→registerObjects().This lets you use a short alias.Use the full namespace with the
newhelper.This avoids registration and resolves the class directly if it exists. It’s also the more efficient option.
The helper follows this signature:
function new(string $class, mixed ...$arguments): objectParameters
| Parameter | Type | Description |
|---|---|---|
$class | string | Fully qualified class name or registered alias. |
$arguments | mixed | Constructor arguments to pass to the class. |
Note
new()is not a PHP function.It works only inside Smarty templates and cannot be used in PHP code.
Examples:
Initialize an object using a registered alias
{{ new('Example', 'param') assign='example' }}Initialize an object using the full namespace
{{ new('\\App\\Utils\\Example') assign='example' }}Use the created object
{{ $example->getName() }}Or access its public properties:
{{ $example->name }}Call Functions
In Luminova Smarty, you can call functions in two ways:
Register them inside
App\Config\Templates\Smarty\Extensions→registerFunctions().This allows you to expose functions as filters, modifiers, plugins, or custom Smarty functions.Call them directly using the
fnhelper.Luminova includes a built-in helper class,Luminova\Template\Extensions\SmartyFunction,which behaves much like Twig’s\Twig\TwigFunctionto keep everything consistent.
NoteEven if you don’t wrap the function name with
fn, Luminova will still resolve the correct function—including Luminova-namespaced helpers and core PHP functions.Thefnhelper is only needed when you explicitly want this behavior inside templates.
Aliases:func, function behave exactly the same as fn.
The helper signature:
function fn(string $function, mixed ...$arguments): mixedParameters
| Parameter | Type | Description |
|---|---|---|
$function | string | The function name (e.g., Luminova\\Funcs\\escape, strlen). |
$arguments | mixed | Optional function arguments. |
Note
fn()is not a PHP function.It only works inside Smarty templates.
Examples:
Call registered or global function
{{ myFunction() }}
{{ root('path/to/file', 'filename.json') }}Call a regular function
{{ fn('myFunction') }}Call a namespaced Luminova helper
{{ fn('Luminova\\Funcs\\root', 'path/to/file', 'filename.json') }}Or call Luminova functions without namespace
{{ fn('root', 'path/to/file', 'filename.json') }}This gives you a simple, uniform way to use PHP and Luminova helper functions directly in your templates without extra setup.
Get Constants
You can access constants in Smarty using the built-in syntax:
{{ $smarty.const.APP_NAME }}Luminova also provides a const helper that retrieves any globally defined constant.This helper is recommended because it keeps your templates future-proof and easier to maintain.
function const(string $name): mixedParameters
| Parameter | Type | Description |
|---|---|---|
$name | string | The constant name to retrieve (e.g., APP_NAME, STATUS_SUCCESS). |
Example:
To print your application name:
{{ const('APP_NAME') }}Both methods work, but using the
consthelper keeps your templates consistent with other Luminova helpers.
Smarty Extensions Registration Pattern
Namespace: App\Config\Templates\Smarty\Extensions
Luminova allows you to register custom functions for Smarty by returning an array of SmartyFunction objects inside your Smarty extension class. Each SmartyFunction maps a name used in templates to a callable handler in PHP.
Basic Function
Here are common ways to define functions using the Luminova\Template\Extensions\SmartyFunction class.
Example:
// /app/Config/Templates/Smarty/Extensions.php
namespace App\Config\Templates\Smarty\Extensions;
use Luminova\Template\Extensions\SmartyFunction;
// In registerFunctions()
return [
new SmartyFunction('hello', static fn(string $value): string => "Hello $value")
];No matter how the function is registered, it can be called in both ways:
Function-style:
{{ hello('World') }}Smarty-style:
{{ hello value='World' }}This will output:
Hello WorldThe only thing that changes is how your callback receives the arguments.
Functions with Parameters
Your function can receive parameters in two different ways.It depends on how you register it and how you plan to call it.
Luminova allows you to choose between:
- Positional arguments – each value is passed as a normal function argument.
- Named arguments – Smarty-style: parameters arrive as one associative array.
Both styles work; you just pick what your function expects.
When positional: true
Your callback receives each parameter in order, just like a normal PHP function.
// In Extensions::registerFunctions()
return [
new SmartyFunction(
'greet',
function(string $name, int $age, array $tools): string {
return "Hi, am {$name}, {$age} years. Tools: " . var_export($tools, true);
},
positional: true
)
];When positional: false
Your callback receives one array containing all parameters.
If you call the function using Smarty-style named parameters, Luminova passes them as key–value pairs.
// In Extensions::registerFunctions()
return [
new SmartyFunction(
'greet',
function(array $data): string {
// You can pick values however you like:
// Use e.g, $data['name'], $data['age'], $data['tools'] for smarty style
[$name, $age, $tools] = array_values($data);
return "Hi, am {$name}, {$age} years. Tools: " . var_export($tools, true);
},
positional: false
)
];Both result in your PHP callback receiving something like:
// PHp Function-style
['0' => 'Peter', '1' => 20, '2' => ['PHP','JS','JAVA','SWIFT']]// Smarty-style
['name' => 'Peter', 'age' => 20, 'tools' => ['PHP','JS','JAVA','SWIFT']]Calling function in template:
Function-style:
{{ greet('Peter', 20, ['PHP', 'JS', 'JAVA', 'SWIFT']) }}Smarty-style:
{{ greet name='Peter' age=20 tools=['PHP', 'JS', 'JAVA', 'SWIFT'] }}Output:
Hi, am Peter, 20 years. Tools: [0 => 'PHP', 1 => 'JS', 2 => 'JAVA', 3 => 'SWIFT']Registering a Modifiers
Modifiers work like |upper, |lower, etc.
// In Extensions::registerFunctions()
return [
new SmartyFunction('upper', 'strtoupper', SmartyFunction::MODIFIER),
new SmartyFunction('lower', 'strtolower', SmartyFunction::MODIFIER)
];Smarty template:
{{ $self.name|upper }}Block Function
Block functions wrap the content between {tag} and {/tag}.
// In Extensions::registerFunctions()
return [
new SmartyFunction(
'bold',
fn($params, $content) => '<strong>' . $content . '</strong>',
SmartyFunction::BLOCK
)
];Smarty template:
{{ bold }}
This text will be bold.
{{ /bold }}Exposing Object Methods
If you want to expose some methods of a class for Smarty to call:
// In Extensions::registerFunctions()
return [
new SmartyFunction(
'example',
new App\Utils\Example(),
type: SmartyFunction::OBJECT,
allowedMethodsProperties: ['getName', 'setName']
)
];Template usage:
{{ example->setName('Peter') }}
{{ $example->getName() }}