PHP Classes

Grammar Template: Template engine in PHP and other languages

Recommend this page to a friend!
  Info   View files Documentation   Demos   Screenshots Screenshots   View files View files (40)   DownloadInstall with Composer Download .zip   Reputation   Support forum   Blog (1)    
Last Updated Ratings Unique User Downloads Download Rankings
2022-08-08 (9 months ago) RSS 2.0 feedNot yet rated by the usersTotal: 163 All time: 8,876 This week: 177Up
Version License PHP version Categories
grammartemplate 3.0.0Artistic License5PHP 5, Templates, Parsers
Description 

Author

This package implements a template engine that can work in PHP and in other languages.

It can parse a given template string that can be processed by the engine to expand to the processed output.

The engine can take parameters that define regular variables or array of variables to replace in the template placeholders, optional blocks, and nested blocks.

The package provides an implementation of the same template engine in PHP, Python and JavaScript that can work with regular browser side JavaScript code, or Node.js or XPCOM Javascript.

Innovation Award
PHP Programming Innovation award nominee
September 2020
Number 6
Template engines are very useful to separate programming logic from presentation logic.

Some applications may need to generate the same presentation from templates either on the server side with a language like PHP, or with on the browser side language like JavaScript.

The package implements a template engine that works in multiple languages including PHP and JavaScript.

This way developers can use this package PHP and JavaScript versions to render the same site presentation using the same template files.

Manuel Lemos
Picture of Nikos M.
Name: Nikos M. <contact>
Classes: 17 packages by
Country: Greece Greece
Innovation award
Innovation award
Nominee: 7x

Winner: 2x

Details

GrammarTemplate

GrammarTemplate versatile and intuitive grammar-based templating for PHP, Python, Browser / Node.js / XPCOM Javascript (see for example here and here and eventualy here)

GrammarTemplate

Etymology of "grammar" Etymology of "template"

light-weight (~7.7kB minified, ~3.2kB zipped)

  • `GrammarTemplate` is also a `XPCOM JavaScript Component` (Firefox) (e.g to be used in firefox browser addons/plugins)

version 3.0.0 GrammarTemplate.js, GrammarTemplate.min.js

Live Playground Example

GrammarTemplate Editor

see also:

  • ModelView a simple, fast, powerful and flexible MVVM framework for JavaScript
  • tico a tiny, super-simple MVC framework for PHP
  • LoginManager a simple, barebones agnostic login manager for PHP, JavaScript, Python
  • SimpleCaptcha a simple, image-based, mathematical captcha with increasing levels of difficulty for PHP, JavaScript, Python
  • Dromeo a flexible, and powerful agnostic router for PHP, JavaScript, Python
  • PublishSubscribe a simple and flexible publish-subscribe pattern implementation for PHP, JavaScript, Python
  • Importer simple class &amp; dependency manager and loader for PHP, JavaScript, Python
  • Contemplate a fast and versatile isomorphic template engine for PHP, JavaScript, Python
  • HtmlWidget html widgets, made as simple as possible, both client and server, both desktop and mobile, can be used as (template) plugins and/or standalone for PHP, JavaScript, Python (can be used as plugins for Contemplate)
  • Paginator simple and flexible pagination controls generator for PHP, JavaScript, Python
  • Formal a simple and versatile (Form) Data validation framework based on Rules for PHP, JavaScript, Python
  • Dialect a cross-vendor &amp; cross-platform SQL Query Builder, based on GrammarTemplate, for PHP, JavaScript, Python
  • DialectORM an Object-Relational-Mapper (ORM) and Object-Document-Mapper (ODM), based on Dialect, for PHP, JavaScript, Python
  • Unicache a simple and flexible agnostic caching framework, supporting various platforms, for PHP, JavaScript, Python
  • Xpresion a simple and flexible eXpression parser engine (with custom functions and variables support), based on GrammarTemplate, for PHP, JavaScript, Python
  • Regex Analyzer/Composer Regular Expression Analyzer and Composer for PHP, JavaScript, Python

API

Grammar Template

A block inside [..] represents an optional block of code (depending on passed parameters) and <..> describe placeholders for query parameters / variables (i.e non-terminals). The optional block of code depends on whether all optional parameters defined inside (with <?..>, <?!..> or <*..> and <{n,m}..> for rest parameters) exist. Then, that block (and any nested blocks it might contain) is output, else bypassed.

A block defined with :=[..] represents a (recursive) sub-template, which can be used to render any deep/structured argument a needed (see below).

var GrammarTemplate = require("../src/js/GrammarTemplate.js"), echo = console.log;

echo('GrammarTemplate.VERSION = ' + GrammarTemplate.VERSION);
echo( );

var tpl = "SELECT <column.select>[, <column.select>]\nFROM <table.from>[, <table.from>][\nWHERE (<?required.where>) AND (<?condition.where>)][\nWHERE <?required.where><?!condition.where>][\nWHERE <?!required.where><?condition.where>][\nGROUP BY <?group>[, <group>]][\nHAVING (<?required.having>) AND (<?condition.having>)][\nHAVING <?required.having><?!condition.having>][\nHAVING <?!required.having><?condition.having>][\nORDER BY <?order>[, <order>]][\nLIMIT <offset|0>, <?count>]";

var sql = new GrammarTemplate( tpl );

echo("input template:");
echo(tpl);

echo( );

echo("output:");
echo(sql.render({
    column      : { select : [ 'field1', 'field2', 'field3', 'field4' ] },
    table       : { from : [ 'tbl1', 'tbl2' ] },
    condition   : { where : 'field1=1 AND field2=2', having : 'field3=1 OR field4=2' },
    count       : 5
}));

output

GrammarTemplate.VERSION = 3.0.0

input template:
SELECT <column.select>[, <*column.select>]
FROM <table.from>[, <*table.from>][
WHERE (<?required.where>) AND (<?condition.where>)][
WHERE <?required.where><?!condition.where>][
WHERE <?!required.where><?condition.where>][
GROUP BY <?group>[, <*group>]][
HAVING (<?required.having>) AND (<?condition.having>)][
HAVING <?required.having><?!condition.having>][
HAVING <?!required.having><?condition.having>][
ORDER BY <?order>[, <*order>]][
LIMIT <offset|0>, <?count>]

output:
SELECT field1, field2, field3, field4
FROM tbl1, tbl2
WHERE field1=1 AND field2=2
HAVING field3=1 OR field4=2
LIMIT 0, 5

var GrammarTemplate = require("../src/js/GrammarTemplate.js"), echo = console.log;

echo('GrammarTemplate.VERSION = ' + GrammarTemplate.VERSION);
echo( );

/*
    i.e: 
    foreach "expression:terms" as "term":
        foreach "term:factors" as "factor":
            ..
    
    here an :EXPR template is defined which itself uses (anonymous) sub-templates
    it is equivalent to (expand sub-templates to distinct):

<:FACTOR>:=[<lhs>[ <?op> <rhs|NULL>]]

<:TERM>:=[(<factor:FACTOR>[ AND <*factor:FACTOR>])]

<:EXPR>:=[<term:TERM>[ OR <*term:TERM>]]

<expression:EXPR>
<expression2:EXPR>

*/

var tpl = "<:EXPR>:=[<term>:=[(<factor>:=[<lhs>[ <?op> <rhs|NULL>]][ AND <factor>])][ OR <term>]]<expression:EXPR>\n<expression2:EXPR>";

var expr = new GrammarTemplate( tpl );

echo("input template:");
echo(tpl);

echo( );

echo("output:");
echo(expr.render({
    expression  : [
        // term
        [
            // factor
            {lhs: 1, op: '=', rhs: 1},
            // factor
            {lhs: 1, op: '=', rhs: 2},
            // factor
            {lhs: 1, op: '=', rhs: 3}
        ],
        // term
        [
            // factor
            {lhs: 1, op: '<', rhs: 1},
            // factor
            {lhs: 1, op: '<', rhs: 2},
            // factor
            {lhs: 1, op: '<', rhs: 3}
        ],
        // term
        [
            // factor
            {lhs: 1, op: '>', rhs: 1},
            // factor
            {lhs: 1, op: '>', rhs: 2},
            // factor
            {lhs: 1, op: '>', rhs: 3}
        ]
    ],
    expression2  : [
        // term
        [
            // factor
            {lhs: 2, op: '=', rhs: 1},
            // factor
            {lhs: 2, op: '=', rhs: 2},
            // factor
            {lhs: 2, op: '=', rhs: 3}
        ],
        // term
        [
            // factor
            {lhs: 2, op: '<', rhs: 1},
            // factor
            {lhs: 2, op: '<', rhs: 2},
            // factor
            {lhs: 2, op: '<', rhs: 3}
        ],
        // term
        [
            // factor
            {lhs: 2, op: '>', rhs: 1},
            // factor
            {lhs: 2, op: '>', rhs: 2},
            // factor
            {lhs: 2, op: '>', rhs: 3}
        ],
        // term
        [
            // factor
            {lhs: 3},
            // factor
            {lhs: 3, op: '!='}
        ]
    ]
}));

output

GrammarTemplate.VERSION = 3.0.0

input template:
<:EXPR>:=[<term>:=[(<factor>:=[<globalNegation:NEG><lhs>[ <?op:OP> <rhs|NULL>]][ AND <factor>])][ OR <term>]]<expression:EXPR>
<expression2:EXPR>

output:
(NOT 1 = 1 AND NOT 1 = 2 AND NOT 1 = 3) OR (NOT 1 < 1 AND NOT 1 < 2 AND NOT 1 < 3) OR (NOT 1 > 1 AND NOT 1 > 2 AND NOT 1 > 3)
(NOT 2 = 1 AND NOT 2 = 2 AND NOT 2 = 3) OR (NOT 2 < 1 AND NOT 2 < 2 AND NOT 2 < 3) OR (NOT 2 > 1 AND NOT 2 > 2 AND NOT 2 > 3) OR (NOT 3 AND NOT 3 <> NULL)

var GrammarTemplate = require("../src/js/GrammarTemplate.js"), echo = console.log;

echo('GrammarTemplate.VERSION = ' + GrammarTemplate.VERSION);
echo( );

var tpl = "<:BLOCK>:=[BLOCK <.name>\n{\n[    <@.blocks:BLOCKS>?\n]}]<:BLOCKS>:=[<@block:BLOCK>[\n<@block:BLOCK>*]]<@blocks:BLOCKS>";

var aligned = new GrammarTemplate( tpl, null, true );

echo("input template:");
echo(tpl);

echo( );

echo("output:");
echo(aligned.render({
    blocks      : [
    {
        name        : "block1",
        blocks      : null
    },
    {
        name        : "block2",
        blocks      : [
            {
                name   : "block21",
                blocks : [
                    {
                        name   : "block211",
                        blocks : [
                            {
                                name   : "block2111",
                                blocks : null
                            },
                            {
                                name   : "block2112"
                            }
                        ]
                    },
                    {
                        name   : "block212"
                    }
                ]
            },
            {
                name   : "block22",
                blocks : [
                    {
                        name   : "block221"
                    },
                    {
                        name   : "block222"
                    }
                ]
            }
        ]
    },
    {
        name        : "block3"
    }
]
}));

GrammarTemplate.VERSION = 3.0.0

input template:
<:BLOCK>:=[BLOCK <.name>
{
[    <@.blocks:BLOCKS>?
]}]<:BLOCKS>:=[<@block:BLOCK>[
<@block:BLOCK>*]]<@blocks:BLOCKS>

output:
BLOCK block1
{
}
BLOCK block2
{
    BLOCK block21
    {
        BLOCK block211
        {
            BLOCK block2111
            {
            }
            BLOCK block2112
            {
            }
        }
        BLOCK block212
        {
        }
    }
    BLOCK block22
    {
        BLOCK block221
        {
        }
        BLOCK block222
        {
        }
    }
}
BLOCK block3
{
}

TODO

  • handle literal symbols (so for example grammar-specific delimiters can also be used literaly, right now delimiters can be adjusted as parameters) [DONE, through escaping]
  • handle nested/deep arguments [DONE, through nested object-dot notation]
  • handle recursion/loop deep structured arguments and sub-templates [DONE, through defining recursive sub-templates for rendering any deep argument]
  • handle boolean-like optional arguments [DONE, through setting (empty) default value for optional argumement, is handled as pure boolean on/off flag argument]
  • optimise parsing and rendering [DONE]
  • support some basic and/or user-defined functions [DONE, similar custom function definition as custom sub-template, calls function if custom function with same name has been defined]
  • support both `pre-` and `post-` (repeat) grammar operators, i.e both `<?symbol>`,`<symbol>,<{n,m}symbol>and<symbol>?,<symbol>`,`<symbol>{n,m}` for more familiar grammar syntax [DONE, via extra parameter in template instantiation]
  • support comments [DONE, through comment block notation, i.e `[# comment here #]`]
  • handle generic/dynamic unknown before-hand custom rendering methods [DONE, can attach to generic wildcard renderer `*` and handle/dispatch based on passed template name]
  • handle same name local and global arguments in (deep) recursive templates, avoiding possible global conflicts and infinite loops [DONE, through explicit local dot `.` argument notation]
  • handle explicit text/code alignment/indentation expansion in sequence [DONE, use aligned `@` argument notation]
  • handle custom delimiters with different lengths and possibly same prefixes [DONE, by dynamicaly arranging parsing by delimiter string length]
  Live DemoExternal page  

Open in a separate window

Screenshots  
  • grammartemplate-editor.png
  Files folder image Files  
File Role Description
Files folder imagesrc (6 directories)
Files folder imagetest (30 files)
Accessible without login Image file grammartemplate.jpg Data Documentation ima
Accessible without login Plain text file README.md Doc. Example script

  Files folder image Files  /  src  
File Role Description
Files folder imageactionscript (1 file)
Files folder imagec (1 file)
Files folder imagejava (1 file)
Files folder imagejs (2 files)
Files folder imagephp (1 file)
Files folder imagepython (2 files)

  Files folder image Files  /  src  /  actionscript  
File Role Description
  Accessible without login Plain text file todo.txt Doc. Documentation

  Files folder image Files  /  src  /  c  
File Role Description
  Accessible without login Plain text file todo.txt Doc. Documentation

  Files folder image Files  /  src  /  java  
File Role Description
  Accessible without login Plain text file todo.txt Doc. Documentation

  Files folder image Files  /  src  /  js  
File Role Description
  Accessible without login Plain text file GrammarTemplate.js Data Auxiliary data
  Accessible without login Plain text file GrammarTemplate.min.js Data Auxiliary data

  Files folder image Files  /  src  /  php  
File Role Description
  Plain text file GrammarTemplate.php Class Class source

  Files folder image Files  /  src  /  python  
File Role Description
  Accessible without login Plain text file GrammarTemplate.py Data Auxiliary data
  Accessible without login Plain text file __init__.py Data Auxiliary data

  Files folder image Files  /  test  
File Role Description
  Accessible without login Plain text file out-align-js Data Auxiliary data
  Accessible without login Plain text file out-align-php Data Auxiliary data
  Accessible without login Plain text file out-align-py Data Auxiliary data
  Accessible without login Plain text file out-delims-js Data Auxiliary data
  Accessible without login Plain text file out-delims-php Data Auxiliary data
  Accessible without login Plain text file out-delims-py Data Auxiliary data
  Accessible without login Plain text file out-expr-js Data Auxiliary data
  Accessible without login Plain text file out-expr-php Data Auxiliary data
  Accessible without login Plain text file out-expr-py Data Auxiliary data
  Accessible without login Plain text file out-js Data Auxiliary data
  Accessible without login Plain text file out-php Data Auxiliary data
  Accessible without login Plain text file out-postop-js Data Auxiliary data
  Accessible without login Plain text file out-postop-php Data Auxiliary data
  Accessible without login Plain text file out-postop-py Data Auxiliary data
  Accessible without login Plain text file out-py Data Auxiliary data
  Accessible without login Plain text file test-alignment.js Data Auxiliary data
  Accessible without login Plain text file test-alignment.php Example Example script
  Accessible without login Plain text file test-alignment.py Data Auxiliary data
  Accessible without login Plain text file test-delims.js Data Auxiliary data
  Accessible without login Plain text file test-delims.php Example Example script
  Accessible without login Plain text file test-delims.py Data Auxiliary data
  Accessible without login Plain text file test-postop-recursion.js Data Auxiliary data
  Accessible without login Plain text file test-postop-recursion.php Example Example script
  Accessible without login Plain text file test-postop-recursion.py Data Auxiliary data
  Accessible without login Plain text file test-recursion.js Data Auxiliary data
  Accessible without login Plain text file test-recursion.php Example Example script
  Accessible without login Plain text file test-recursion.py Data Auxiliary data
  Accessible without login Plain text file test.js Data Auxiliary data
  Accessible without login Plain text file test.php Example Example script
  Accessible without login Plain text file test.py Data Auxiliary data

 Version Control Unique User Downloads Download Rankings  
 100%
Total:163
This week:0
All time:8,876
This week:177Up