WackoWiki: Templatest Template Engine: Technical Documentation

https://wackowiki.org/doc     Version: 1 (04/23/2026 02:00)

Templatest Template Engine: Technical Documentation

Comprehensive technical documentation for the Templatest template engine:



Introduction


Templatest is a sophisticated, transition-style template engine for WackoWiki that combines:

The engine prioritizes performance through compilation-time optimization while maintaining flexibility for runtime customization.

Key Characteristics

Architecture Overview

Class Hierarchy


Templatest (Compiler & Factory)
    ↓
TemplatestSetter (Setting & Patching)
    ↓
TemplatestFilters (Filter Pipeline)
    ↓
TemplatestEscaper (Security & Encoding)
    ↓
TemplatestUser (Public API & Rendering)	

Processing Pipeline


Template File
     ↓
[Parsing] → parse_file()
     ↓
[Definition Extraction] → inline_definitions()
     ↓
[Compilation] → compile()
     ↓
[Static Optimization] → inline_static_subs()
     ↓
[Default Application] → inline_defaults()
     ↓
[Caching] → serialize to cache file
     ↓
TemplatestUser Instance (Ready for use)	

Core Concepts

1. Patterns


Patterns are named template blocks that serve as reusable components. They're the fundamental building unit of Templatest.

[ ==== patternname ==== ]
    template content here
[ ==== otherpattern ==== ]
    other content	

2. Variables


Variables are placeholders within patterns that receive data at runtime.

[ ==== mypattern ==== ]
Hello, [ ' name ' ]!	


Variables are:

3. Subpatterns


Subpatterns are pattern references within other patterns, enabling composition.

[ ==== layout ==== ]
<div class="header">[ ' header ' ]</div>
<div class="content">[ ' content ' ]</div>

[ ==== page ==== ]
This is the page content	


When layout is rendered with set('content', 'page'), the page pattern is inserted into the content placeholder.

4. Pull Actions


Pull functions are runtime callbacks for dynamic content generation (CSRF tokens, internationalization, etc.).

[ ==== form ==== ]
<form>
    [ ' csrf: ' ]
    [ ' form_fields: ' ]
</form>	


Format: [ ' actionname: args ' ]

Template Syntax

Tag Structure


Tags use a quoted-content pattern with optional pipes:

[ ' tag_content | filter1 arg1 | filter2 arg1 arg2 ' ]	

Quote Levels


The number of quotes determines tag recognition:

[ ' content ' ]     - single quotes (standard)
[ '' content '' ]   - double quotes (requires double quotes to open)
[ ''' content ''' ] - triple quotes (requires triple quotes to open)	


This prevents premature tag matching when quotes appear in content.

Comments


[ ==== // this is a comment ==== ]
[ ==== # this is also a comment ==== ]	

Directives (Outside Patterns)


Directives appear before any pattern definition:

.escape – Set default escaping mode


.escape html              # Apply HTML escaping to all patterns
.escape js mypattern      # Apply JavaScript escaping only to mypattern	


Valid modes:

.patch – Set default values


.patch mypattern varname defaultvalue	

.include – Include external templates


.include path/to/template.tpl	


Maximum inclusion depth: 5 levels (circular includes prevented)

Patterns and Variables

Pattern Definition


Patterns are defined with equals signs indicating hierarchy:

[ ==== main ==== ]              # Main pattern
[ === section === ]             # Section header (not used for separation)
[ == subsection == ]            # Subsection (flexible)	


All are equivalent; the number of = signs is cosmetic. The pattern name must:

Variable Assignment


Variables are declared and referenced with quotes:

Template Definition:
    [ ' username ' ]
    [ ' user.email ' ]
    [ ' status | default "pending" ' ]

PHP Usage:
    $tpl->set('username', 'John');
    $tpl->set('user', ['email' => 'john@example.com']);
    $tpl->set('status', null);  // Uses default	

Block vs. Inline Usage


Templatest automatically detects usage context:

Block Usage (tag alone on line with optional indentation):

<div class="content">
    [ ' message ' ]
</div>	


Result: Automatic indentation applied

html
<div class="content">
    Rendered content here
</div>	


Inline Usage (tag within line content):

<p>Hello [ ' name ' ]!</p>	


Result: No indentation, whitespace trimmed

html
<p>Hello John!</p>	

Nested Pattern Usage (Subpatterns)


Reference patterns within patterns:

[ ==== header ==== ]
<h1>[ ' title ' ]</h1>

[ ==== page ==== ]
[ ' header ' ]
<p>[ ' content ' ]</p>	


Usage:
php
$page = Templatest::read('template.tpl');
$page->set('header', ['title' => 'Welcome']);  // Header pattern
$page->set('content', 'Page content');          // Page pattern var	

Context Navigation


For complex hierarchies, use context helpers:

php
$tpl = Templatest::read('template.tpl');

$i = $tpl->enter('user');           // Enter user context
$tpl->set('name', 'John');          // Sets user_name
$tpl->set('profile', 'Developer');  // Sets user_profile
$tpl->leave();                       // Exit context

// Equivalent to:
$tpl->set('user_name', 'John');
$tpl->set('user_profile', 'Developer');	

Tag System

Tag Components


A complete tag has the structure:

[ ' primary_action | filter1 args | filter2 args ' ]	

Primary Actions

1. Variable Reference


[ ' varname ' ]
[ ' varname | filter1 | filter2 ' ]	

2. Pattern Reference


[ ' patternname ' ]          # Call pattern with its own variables
[ ' varname patternname ' ]  # Assign pattern to variable	

3. Pull Action


[ ' action: arg1 arg2 ' ]	


Registers a callback that will be invoked during rendering.

4. Dot Notation (Sugar)


[ ' user.name ' ]  →  [ ' user | .name ' ]	


Automatically converted to index filter application.

Pipe System


Pipes connect filters in sequence:

[ ' value | filter1 arg1 | filter2 arg2 | filter3 ' ]	


Each filter's output becomes the next filter's input.

Filters and Processing

Filter Execution


Filters are applied in order during the assign() phase:

  1. Input value
  2. Apply filter1(value, arg1) → intermediate
  3. Apply filter2(intermediate, arg2) → result
  4. Apply filter3(result) → final
  5. Apply default escaping
  6. Return final value	

Built-in Filters

String Transformation


php
filter_lower($value)                              // Lowercase
filter_upper($value)                              // Uppercase
filter_trim($value, $character_mask)              // Trim whitespace
filter_replace(args...)                           // Multiple replacements
filter_regex($value, $re, $to, $limit, $strict)  // Regex replacement	

Formatting


php
filter_format($value, $fmt)                       // sprintf()
filter_date($value, $fmt)                         // date()
filter_number($decimals, $dec_pt, $thousands_sep) // number_format()
filter_join($value, $glue)                        // implode()
filter_stringify($value)                          // Convert to string	

HTML/Content


php
filter_nl2br($value)                              // Newlines to <br>
filter_spaceless($value)                          // Collapse whitespace (preserve <pre>, <textarea>)
filter_striptags($value, $allowable_tags)        // strip_tags()
filter_truncate($value, $limit, $ellipsis)       // Truncate with ellipsis	

Data Processing


php
filter_index($value, $path)                       // Array/object access
filter_split($value, $delimiter, $limit)         // Explode/str_split
filter_json_encode($value, ...options)            // JSON encode
filter_json_decode($value)                        // JSON decode
filter_list($index, ...items)                     // Select from list
filter_default($value, $default)                  // Provide default
filter_void($value)                               // Return null	

URL/Encoding


php
filter_escape_also_e($value, $mode)               // Escape: html, js, css, url, attr, raw
filter_url_encode($value)                         // URL encoding (handles arrays)	

Utility


php
filter_check($value, $on)                         // Checkbox value/checked helper
filter_checkbox($value)                           // Checkbox checked helper
filter_select($value, $on)                        // Select option selected helper
filter_enclose($value, $pref, $post)             // Wrap with prefix/postfix
filter_sp2nbsp($value)                            // Spaces to &nbsp;
filter_dbg($value)                                // Debug output (returns value)
filter_pre($value)                                // Suppress indentation for value	

Escaping

Default Escaping


Values are automatically escaped based on pattern configuration:

php
// At compile time
.escape html      // HTML escaping
.escape js        // JavaScript escaping

// At runtime
filter_escape_also_e($value, 'html')   // Explicit escaping	

Escape Modes


html       - &lt;script&gt; → HTML entities
js         - "string" → \x22string\x22 (Unicode escaping)
css        - #id { → \23 id\20 \7b\20  (hex escaping)
url        - spaces → %20 (percent encoding)
attr       - comprehensive HTML attribute safety
raw        - No escaping (use with caution)	

Custom Filters


Register custom filter functions:

php
$tpl = Templatest::read('template.tpl');

// Add a custom filter
$tpl->filter('customfilter', function($value, $arg1, $arg2) {
    // Process and return value
    return $value;
});

// Now usable in templates
[ ' myvar | customfilter arg1 arg2 ' ]	

Advanced Features

1. Static Optimization


Templatest identifies static content at compile time and optimizes it:

Pattern with static subpattern:
    [ ==== box ==== ]
    <div>[ ' content ' ]</div>

    [ ==== footer ==== ]
    <footer>© 2026</footer>   ← Static (no variables)

Optimization:
    - footer pattern marked as static
    - Inlined into parent pattern during compilation
    - Reduces rendering overhead	

2. Auto-Indentation


Block-level variables automatically inherit parent indentation:

Template:
    <ul>
        [ ' items ' ]
    </ul>

Setting:
    $tpl->set('items', "
        <li>Item 1</li>
        <li>Item 2</li>
    ");

Result:
    <ul>
        <li>Item 1</li>
        <li>Item 2</li>
    </ul>	


The 4-space indent is automatically applied to each line.

3. Caching


Templates are automatically cached for performance:

php
// Cache operations
$tpl = Templatest::read('template.tpl', '/path/to/cache/dir');

// Cache features:
// - Serialized compiled template stored
// - Automatically invalidated if source changes
// - Write-bit control: chmod 000 disables caching for that file
// - CODE_VERSION check prevents version mismatch	


Cache file naming:
template.tpl  →  template@tpl (slashes converted to @)	

4. Conditional Defaults


The default filter with static assignment:

Template:
    [ ' status | default "pending" ' ]

Setting with null:
    $tpl->set('status', null);    # Uses "pending"
    $tpl->set('status', false);   # Uses "pending"
    $tpl->set('status', 'active'); # Uses "active"	

5. Pattern Cloning


Access different patterns through magic methods:

php
$main_tpl = Templatest::read('template.tpl');  // Main pattern
$header = $main_tpl->header();                  // Clone with header pattern
$footer = $main_tpl->footer();                  // Clone with footer pattern

// Each is independently renderable
echo $header->set('title', 'Welcome');
echo $footer->set('year', 2026);	

Developer Guide

Loading and Initialization


php
// Basic loading
$tpl = Templatest::read('/path/to/template.tpl');

// With caching
$tpl = Templatest::read('/path/to/template.tpl', '/path/to/cache');

// Clone for specific pattern
$header = $tpl->header();
$page = $tpl->page();	

Setting Data


php
// Simple variable
$tpl->set('name', 'John');
$tpl->set('age', 30);

// Array (will use default filter)
$tpl->set('items', ['Apple', 'Banana', 'Orange']);

// Nested variables (underscore syntax)
$tpl->set('user_name', 'John');
$tpl->set('user_email', 'john@example.com');

// Equivalent with context
$i = $tpl->enter('user');
$tpl->set('name', 'John');
$tpl->set('email', 'john@example.com');
$tpl->leave();

// Array-style setting
$tpl->set(['user' => ['name' => 'John', 'email' => 'john@example.com']]);

// Multiple values
$tpl->set('header', 'Welcome', 'content', 'Body text', 'footer', 'Footer');	

Adding Pull Functions


php
// Define a pull handler
$tpl->pull('csrf', function($is_block, $location) {
    return htmlspecialchars($_SESSION['csrf_token']);
});

$tpl->pull('i18n', function($is_block, $location, $key, $lang = 'en') {
    return get_translation($key, $lang);
});

// Usage in template:
// [ ' csrf: ' ]
// [ ' i18n: "welcome.message" "fr" ' ]	

Adding Custom Filters


php
// Single filter
$tpl->filter('md5', function($value) {
    return md5($value);
});

// Filter with parameters
$tpl->filter('truncate_custom', function($value, $length, $suffix = '...') {
    return substr($value, 0, $length) . $suffix;
});

// Usage in template:
// [ ' email | md5 ' ]
// [ ' description | truncate_custom 50 "..." ' ]	

Character Encoding


php
// Set encoding (defaults to UTF-8)
$tpl->setEncoding('utf-8');
$tpl->setEncoding('iso-8859-1');

// Get current encoding
$encoding = $tpl->getEncoding();

// Supported encodings (per htmlspecialchars):
// iso-8859-1, iso-8859-5, iso-8859-15
// cp866, cp1251, cp1252
// koi8-r, koi8-ru
// big5, gb2312
// shift_jis, euc-jp, macroman, etc.	

Rendering


php
// Direct rendering (uses __toString)
echo $tpl;

// Explicit render
echo (string) $tpl;

// Get as string
$html = $tpl->__toString();	

Error Handling


Errors are triggered with E_USER_WARNING:

php
// Configure error handler
set_error_handler(function($errno, $errstr) {
    if (strpos($errstr, 'templatest') !== false) {
        // Handle template error
        error_log($errstr);
    }
});

// Template errors include:
// - Unknown filters
// - Invalid tags
// - Undefined variables
// - Pattern redefinition
// - File not found	

Examples

Example 1: Basic Layout


Template File (layout.tpl):
[ ==== layout ==== ]
<!DOCTYPE html>
<html>
<head>
    <title>[ ' title ' ]</title>
</head>
<body>
    <header>
        [ ' header ' ]
    </header>
    <main>
        [ ' content ' ]
    </main>
    <footer>
        [ ' footer ' ]
    </footer>
</body>
</html>

[ ==== simple_header ==== ]
<h1>[ ' h1_text ' ]</h1>

[ ==== simple_footer ==== ]
<p>&copy; [ ' year | default "2026" ' ]</p>	


PHP Code:
php
$tpl = Templatest::read('layout.tpl', '/cache');

$tpl->set('title', 'My Website');
$tpl->set('header', 'simple_header');
$tpl->set('h1_text', 'Welcome!');
$tpl->set('content', '<p>Main content here</p>');
$tpl->set('footer', 'simple_footer');
$tpl->set('year', 2026);

echo $tpl;	

Example 2: Form with CSRF Protection


Template File (form.tpl):
.escape html

[ ==== form ==== ]
<form method="POST">
    [ ' csrf: ' ]
    [ ' form_fields ' ]
    <button type="submit">[ ' button_text | default "Submit" ' ]</button>
</form>

[ ==== text_field ==== ]
<div class="form-group">
    <label>[ ' label ' ]</label>
    <input type="text" name="[ ' name ' ]" value="[ ' value | default "" ' ]">
</div>

[ ==== textarea_field ==== ]
<div class="form-group">
    <label>[ ' label ' ]</label>
    <textarea name="[ ' name ' ]">[ ' value | default "" ' ]</textarea>
</div>	


PHP Code:
php
$tpl = Templatest::read('form.tpl', '/cache');

// Add CSRF pull handler
$tpl->pull('csrf', function($is_block, $location) {
    $token = htmlspecialchars($_SESSION['csrf_token']);
    return '<input type="hidden" name="csrf_token" value="' . $token . '">';
});

// Build form fields
$fields_html = '';

// Text field
$field = $tpl->text_field();
$field->set('label', 'Email');
$field->set('name', 'email');
$field->set('value', 'user@example.com');
$fields_html .= $field;

// Textarea field
$field = $tpl->textarea_field();
$field->set('label', 'Message');
$field->set('name', 'message');
$fields_html .= $field;

$tpl->set('form_fields', $fields_html);
$tpl->set('button_text', 'Send');

echo $tpl;	

Example 3: Data List with Filters


Template File (list.tpl):
[ ==== product_list ==== ]
<ul class="products">
    [ ' items ' ]
</ul>

[ ==== product_item ==== ]
<li class="product">
    <h3>[ ' name | upper ' ]</h3>
    <p>[ ' description | truncate 100 ' ]</p>
    <span class="price">[ ' price | number 2 "," "." ' ]</span>
    <span class="status">[ ' active | select 1 ' ]Status: In Stock</span>
</li>	


PHP Code:
php
$tpl = Templatest::read('list.tpl', '/cache');

$items_html = '';
$products = [
    ['name' => 'laptop', 'description' => 'High-performance computing device...', 'price' => 999.99, 'active' => 1],
    ['name' => 'mouse', 'description' => 'Wireless mouse for productivity...', 'price' => 29.99, 'active' => 1],
    ['name' => 'keyboard', 'description' => 'Mechanical keyboard...', 'price' => 149.99, 'active' => 0],
];

foreach ($products as $product) {
    $item = $tpl->product_item();
    $item->set('name', $product['name']);
    $item->set('description', $product['description']);
    $item->set('price', $product['price']);
    $item->set('active', $product['active']);
    $items_html .= $item;
}

$tpl->set('items', $items_html);

echo $tpl;	

Example 4: Internationalization with Pull


Template File (i18n.tpl):
[ ==== page ==== ]
<h1>[ ' title: "page.title" ' ]</h1>
<p>[ ' description: "page.description" ' ]</p>
<button>[ ' button: "actions.submit" ' ]</button>	


PHP Code:
php
$translations = [
    'en' => [
        'page.title' => 'Welcome',
        'page.description' => 'This is a test page',
        'actions.submit' => 'Submit',
    ],
    'fr' => [
        'page.title' => 'Bienvenue',
        'page.description' => 'Ceci est une page de test',
        'actions.submit' => 'Soumettre',
    ],
];

$current_lang = 'fr';

$tpl = Templatest::read('i18n.tpl', '/cache');

$tpl->pull('title', function($is_block, $location, $key) use ($translations, $current_lang) {
    return htmlspecialchars($translations[$current_lang][$key] ?? $key);
});

$tpl->pull('description', function($is_block, $location, $key) use ($translations, $current_lang) {
    return htmlspecialchars($translations[$current_lang][$key] ?? $key);
});

$tpl->pull('button', function($is_block, $location, $key) use ($translations, $current_lang) {
    return htmlspecialchars($translations[$current_lang][$key] ?? $key);
});

echo $tpl;	

Performance Considerations

Caching

Static Optimization


The engine automatically optimizes:

Large Templates

Troubleshooting

Template Not Found


Error: template file /path/to/template.tpl not found	


Solution: Verify file path and readable permissions

No Main Template Found


Error: no main template found in /path/to/template.tpl	


Solution: Define at least one pattern with [ ==== name ==== ]

Unknown Filter


Warning: unknown filter 'myfilter' at /path/to/template.tpl:15	


Solution: Register filter with $tpl->filter('myfilter', $callback)

Too Deep Template Inclusion


Error: too deep template inclusion	


Solution: Maximum inclusion depth is 5 levels. Reorganize template includes.

Pattern Redefinition


Error: attempt of redefining pattern 'name' at /path/to/template.tpl:10	


Solution: Pattern names must be unique within a file.

Summary


Templatest provides a powerful, efficient template engine optimized for WackoWiki. By understanding:
  1. Patterns as reusable components
  2. Variables for dynamic content
  3. Filters for data transformation
  4. Pull/Push duality for flexible rendering
  5. Caching for performance

Developers can create maintainable, high-performance templates with strong security defaults (HTML escaping) and extensibility through custom filters and pull handlers.