- Introduction
- How It Works
- Installation
- Basic Usage
- Template Syntax
- Blocks and Variables
- Arithmetic Operations
- Conditional Logic
- Working with Loops
- Callback Functions
- Error Handling
- Performance Optimization
- History
- License
XTemplate SE
(Seditio Edition) is a modern and enhanced version of the classic XTemplate
templating engine for PHP. Designed to separate application logic from presentation, it offers advanced features such as nested blocks, arithmetic operations, conditional logic, loops, and callback functions. It is suitable for both simple and complex projects where flexibility and performance are key.
XTemplate SE
employs an object-oriented model for template processing, setting it apart from the older XTemplate
class. The concept of this object-oriented approach was inspired by the Cotemplate
templating engine from the Cotonti project, but it has been completely reworked and significantly improved for greater flexibility and performance.
- Object Structure:
- Templates are broken down into objects:
XtplBlock
(blocks),XtplVar
(variables),XtplExpr
(expressions),XtplData
(data), andXtplLogical
(conditions). - Each template element is represented as a class instance, enabling flexible parsing and rendering, unlike the linear processing of the old
XTemplate
.
- Templates are broken down into objects:
- Expression Handling:
- Arithmetic and logical operations are processed via
XtplExpr
using Reverse Polish Notation (RPN) for accurate evaluation with proper precedence and parentheses support. - The old
XTemplate
relied on basic regex-based expression handling with limited functionality.
- Arithmetic and logical operations are processed via
- Enhanced Tokenization:
- Dynamic tokenization supports complex constructs (parentheses, operator precedence), replacing the static approach of the previous version.
- Advantages Over Old XTemplate:
- Extensibility: Easy to add new operators and functions.
- Reliability: Built-in error handling (e.g., division by zero).
- Performance: Lazy evaluation of expressions and template structure caching.
Example: {NUM1 + NUM2}
is converted to RPN (NUM1 NUM2 +
), evaluated with precedence, and returns the correct result.
- Download the
XTemplate.php
file from the repository. - Include it in your project:
<?php
require_once 'XTemplate.php';
No additional dependencies are required.
PHP 5.4.0 or higher
Mbstring
PCRE
Hash
Create a template, assign variables, and render the output:
<?php
require_once 'XTemplate.php';
$xtpl = new XTemplate('template.tpl');
$xtpl->assign('USERNAME', 'John Doe');
$xtpl->parse('MAIN');
$xtpl->out('MAIN');
Template template.tpl
:
<!-- BEGIN: MAIN -->
<h1>Hello, {USERNAME}!</h1>
<!-- END: MAIN -->
Output:
<h1>Hello, John Doe!</h1>
- Variables:
{VAR}
— Inserts the value of a variable. - Blocks:
<!-- BEGIN: BLOCK --> ... <!-- END: BLOCK -->
— Defines repeatable or conditional sections. - Comments:
<!-- ... -->
— Ignored during processing.
Blocks structure the template, while variables are substituted within them.
Example:
<!-- BEGIN: MAIN -->
<div>
<p>Name: {USER.name}</p>
<p>Score: {USER.score}</p>
</div>
<!-- END: MAIN -->
PHP:
$xtpl->assign('USER', ['name' => 'Alice', 'score' => 95]);
$xtpl->parse('MAIN');
$xtpl->out('MAIN');
Output:
<div>
<p>Name: Alice</p>
<p>Score: 95</p>
</div>
Supported operations: +
, -
, *
, /
, %
:
* Numeric: `{NUM1 + NUM2}`, `{PRICE - DISCOUNT}`
* String: `{STR1 + STR2}` (concatenation)
Example:
<p>Total: {ITEM.price - ITEM.discount}</p>
PHP:
$xtpl->assign('ITEM', ['price' => 10, 'discount' => 2]);
Output:
<p>Total: 8</p>
Use <!-- IF -->
for conditions:
* Comparison operators: `==`, `===`, `!=`, `!==`, `<`, `>`, `<=`, `>=`
* Logical operators: `AND`, `OR`, `XOR`, `!`
Example:
<!-- IF {SCORE} > 80 -->
<p>High score!</p>
<!-- ELSE -->
<p>Try harder.</p>
<!-- ENDIF -->
PHP:
$xtpl->assign('SCORE', 85);
Output:
<p>High score!</p>
Complex conditions with parentheses:
<!-- IF ( {NUM1} > {NUM2} ) AND ( {NUM3} < {NUM4} ) -->
<p>Complex condition met</p>
<!-- ENDIF -->
Use nested blocks or <!-- FOR -->
loops to iterate over arrays.
Example:
<!-- BEGIN: MAIN -->
<ul>
<!-- BEGIN: ITEMS -->
<li>{ITEM.name} - ${ITEM.price}</li>
<!-- END: ITEMS -->
</ul>
<!-- END: MAIN -->
PHP:
$xtpl->assign('ITEMS', [
['name' => 'Book', 'price' => 15],
['name' => 'Pen', 'price' => 2]
]);
$xtpl->parse('MAIN.ITEMS');
$xtpl->parse('MAIN');
Output:
<ul>
<li>Book - $15</li>
<li>Pen - $2</li>
</ul>
Use <!-- FOR {VALUE} IN {ARRAY} -->
to iterate over array values, or <!-- FOR {KEY}, {VALUE} IN {ARRAY} -->
to access both keys and values.
Example:
<!-- FOR {VALUE} IN {MY_ARRAY} -->
<p>Item: {VALUE}</p>
<!-- ENDFOR -->
PHP:
$xtpl->assign('MY_ARRAY', ['Apple', 'Banana', 'Orange']);
$xtpl->parse('MAIN');
Output:
<p>Item: Apple</p>
<p>Item: Banana</p>
<p>Item: Orange</p>
Example:
<!-- FOR {KEY}, {VALUE} IN {MY_ARRAY} -->
<p>{KEY}: {VALUE}</p>
<!-- ENDFOR -->
PHP:
$xtpl->assign('MY_ARRAY', ['a' => 'Apple', 'b' => 'Banana', 'c' => 'Orange']);
$xtpl->parse('MAIN');
Output:
<p>a: Apple</p>
<p>b: Banana</p>
<p>c: Orange</p>
Add modifiers using |
:
* `{VAR|func}` — Applies the function `func` to `VAR`.
* `{VAR|func($this, arg)}` — Passes arguments.
Example:
<p>Last login: {LAST_LOGIN|strtotime|date('Y-m-d', $this)}</p>
PHP:
$xtpl->assign('LAST_LOGIN', '2025-03-07 12:00:00');
Output:
<p>Last login: 2025-03-07</p>
Division by zero (/
, %
) returns messages: "Division by zero"
, "Modulo by zero"
. Unknown operators throw an "Unknown operator"
exception.
Example:
<p>{NUM / ZERO}</p>
Output:
<p>Division by zero</p>
For comprehensive error handling, add a try-catch
block in XtplVar::evaluate()
.
- Caching: Templates are parsed once and stored in memory.
- Lazy Loading: Variables are evaluated only when
parse()
is called. - Tip: Minimize nested blocks and complex expressions for large datasets.
- v1.2.0: Add callback function filtering to XTemplate. Add XTemplate::configure() for global settings initialization
- v1.1.0: Fixed
%
operator support and improved error handling. - v1.0.0 (2025-03-07): Initial release with support for blocks, variables, arithmetic, conditions, and loops.
The project is licensed under the BSD 3-Clause License. You are free to use, modify, and distribute the code provided the license terms are followed.