Template Syntax

Parenthesis & Quotes

The template engine defines a clear and consistent syntax using three types of bracket pairs. Each pair serves a specific purpose to keep templates readable and structured.


{{ /* expression or variable goes here */ }}
    

{% /* directives like if, for, block ... etc */ %}
    

{-- /* comments */ --}
    

Both single (') and double (") quotes are supported in directives that accept quoted parameters.


{% block '...' %}

{% block "..." %}
    

Printing Variables

Printing variables is one of the core features of the template engine. Variables passed from the controller can be rendered directly inside templates using double curly brackets. All variables must include the $ prefix, similar to PHP.


$this->render('message', [
    'name' => 'Ahmed',
    'age'  => 15
], true);
    

message.template.html


<p>{{ $name }}</p>
<p>{{ $age }}</p>

<p>{{ $name . ' ' . $age }}</p>

<p>{{ $name }} {{ $age }}</p>
    

Expression Evaluation

In addition to printing variables, any valid PHP expression may be evaluated and rendered. Most built-in PHP functions are supported, except unsafe functions.


{{ 1 + 2 + 3 }}

{{ !empty($foo) ? 'Yes' : 'No' }}

{{ date('Y-m-d') }}
    

Variables can also be reassigned inside templates. Assignments do not produce output.


{{ $foo = 1 + 2 }}

{{ $foo }}
    

Comments

Comments may span single or multiple lines. Any content wrapped inside comment tags will not be executed or rendered.


{-- {{ strtolower('ABC') }} This line will not execute --}

{--
    Multiple
    lines
    comment !

    {% if ($num > 5) %}
        This condition will never be resolved
    {% end_if %}
--}
    

Extend & Include Templates

To promote reusability and structured layouts, the engine provides directives for extending base templates and including partial templates.

base.template.html


<div class="main">
    <p>Base Template</p>
</div>
    

app.template.html


{% extend 'base' %}
    

The extend directive accepts the template name without the .template.html extension.

The include directive allows reusing partial templates such as components or reusable UI elements.


<form class="create-post-form">
    <input type="text" name="title" />

    {% include 'submit-button' %}
</form>
    

Dot Notation Path

Templates can be organized inside sub-directories. Dot notation is used to reference templates located in nested folders.


<form class="create-post-form">
    <input type="text" name="title" />

    {% include 'components.submit-button' %}
</form>

{% extend 'admin.layouts.master' %}
    

The engine resolves these paths starting from the configured templates root directory:


components.submit-button  -->  Views/components/submit-button.template.html
admin.layouts.master      -->  Views/admin/layouts/master.template.html
    

Relative Path

When including or extending templates located in the same directory, writing the full dot-notation path can become unnecessarily verbose. SigmaPHP Template provides a relative-path operator to simplify this scenario.

Consider the following structure:


/very/long/path/to/admin/dashboard/default.template.html
/very/long/path/to/admin/dashboard/_partial.template.html
    

Without relative paths, including the partial would require the full dot notation:


{% include 'very.long.path.to.admin.dashboard._partial' %}
    

Using the relative-path operator ./, the engine automatically resolves the template from the current directory:


{% include './_partial' %}
    

Blocks

Blocks provide a structured way to inject content into base templates. The block directive defines a section, while show_block renders its content.

master.template.html


<html>
    <head>
        {% show_block 'title' %}
    </head>

    <body>
        {% show_block 'content' %}
    </body>
</html>
    

app.template.html


{% extend 'master' %}

{% block 'title' %}Home Page{% end_block %}

{% block 'content' %}
<article>Page Content</article>
{% end_block %}
    

Child blocks override parent blocks. To avoid mandatory implementation, a default block definition may be added in the base template:


{% block 'js' %}{-- Could be empty --}{% end_block %}
{% show_block 'js' %}
    

Block names may contain letters, numbers, underscores, dots, and dashes. A block name cannot be purely numeric but may start with a number.


{% block 'test1001' %}
{% block '123test' %}
{% block 'small_article_container' %}
{% block 'alert-message' %}
    

Optionally, the block name may also be specified in the closing directive:


{% block 'my-block' %}
    // block content
{% end_block 'my-block' %}
    

Defining Variables

Although defining variables inside templates is generally discouraged, the engine provides a define directive for cases where local transformations or formatting are required.


{% define $x = 100 %}

{{ $x }}
    

Variables must follow PHP naming conventions and must always have a default value.


{% define $name = "John Doe" %}

{% define $num = 1 + 2 + 3 %}
    

Variables may reference other variables:


{% define $userAge = $user->age %}
{% define $age = $userAge %}

{{ "User age : " . $age }}
    

Variables may be redefined. Redefinition is treated as reassignment:


{% define $x = 5 %}
{% define $x = 10 %}
            

Variables are globally scoped and cannot be defined inside conditional statements, loops, or blocks. Doing so will result in an exception.


{% if (...) %}
    {% define $x = 5 %}
{% end_if %}

{% for ... in ... %}
    {% define $x = 5 %}
{% end_for %}

{% block 'example' %}
    {% define $x = 5 %}
{% end_block %}
            

Conditions

To control the flow of your templates, you can use conditional directives to determine which parts should be rendered, hidden, or processed. A condition is a valid PHP expression that evaluates to true or false. It can rely on:


{% if ($test1 == 'FOO') %}
    Test 1 equals : Foo
{% else_if (1 + 1) %}
    Test 2
{% else_if (false) %}
    Test 3
{% else %}
    Do something ...
{% end_if %}
    

Both if and else_if conditions must be wrapped in parentheses (...). You may use a full if / else_if / else chain or a simple if / end_if pair. Conditions can also be written inline.


{% define $show_block = true %}

{% if ($show_block ) %}
    {% show_block 'list-block' %}
{% end_if %}

<img src="{%{ $imageSrc }%}" class="{% if ($haveClass) %} mx-100 {% end_if %}" />

{% if (($val > 0) && ($val < 100)) %}
    <p>Do something with {%{ $val }%}</p>
{% else %}
    Invalid value : %{%{ $val }%}
{% end_if %}
    

Nested conditions are fully supported:


{%if (($val > 0) && ($val < 100)) %}
    <p>Do something with %{%{ $val }%}</p>
{%else %}
    {%if ($val > 100) %}
        <h1>The value is too large</h1>
    {%else_if ($val < 0) %}
        <h1>The value is too small</h1>
    {%else_if ($val == 0) %}
        <h1>The value can't be zero</h1>
    {%end_if %}
{%end_if %}
    

Loops

Looping directives are another type of control statement. Looping is a core feature in any template engine, allowing you to iterate over data and generate dynamic content.

SigmaPHP-Template provides a for ... in directive that can iterate over numbers, strings, and arrays.


{% for $letter in 'abcd' %}
    {%{ $letter }%}
{% end_for %}

{% for $num in 5 %}
    {%{ $num }%}
{% end_for %}
    

Working with arrays and accumulating values:


{% define $sum = 0 %}

{% for $i in [1, 2, 3, 4, 5] %}
    {%{ $sum = $sum + $i }%}
{% end_for %}

{%{ $sum }%}
    

Looping through an array of items:


{% for $item in $items %}
    {%{ "{$item['id']} : {$item['name']}" }%}
{% end_for %}
    

The engine also provides break and continue directives to control loop execution. Both directives require a condition.


{% for $item in $items %}
    {% break ($item['id'] == 8) %}

    {%{ "{$item['id']} : {$item['name']}" }%}
{% end_for %}

{% for $num in 10 %}
    {% continue ($num % 2 == 0) %}

    {%{ $num }%}
{% end_for %}
    

Nested loops are supported as well:


{% for $i in 2 %}
    {% for $j in 3 %}
        {% for $k in 4 %}
            {%{ $i * $j * $k }%}
        {% end_for %}
    {% end_for %}
{% end_for %}
    
Back to top