The WebAbility® Network Developers - Documentation
WebAbility Site
Templates reference

I. Introduction


The DomCore template system is based on the injection of parameters, language translation strings and data fields directly into the HTML (Or any other language you need) template.

The HTML itself (or any other language) is a fixed code not directly used by the template system, but used to dress the data you want to represent in your prefered language.

The templates are prepared to work with the Box Model programmation ( used by WebAbility® ).

The injection of data is based on an array of values that can be nested into another array and so on.
The template compiler recognize nested arrays to automatically make loops on the information.

The macrolanguage is extremely simple and is made to be usefull and really separate PHP programation from template code (not like other generic PHP template systems like smarty or wordpress templates that completely mix code and PHP).

Templates are made to store reusable HTML code, and overall easily changeable by NON PROGRAMMING PEOPLE.

In sight to create and use templates, you have all those possible options to use:

  • Comments
  • Nested templates, to store many pieces of HTML
  • Simple elements, to replace by values in the template. There are various types of simple elements:
  • Parameters
  • Language entries
  • Fields of values
  • Meta elements, to build a code based on a data array. There are various types of meta elements:
  • Data access with {{...}}, to show the value of a data into the data array
  • Subtemplates access with &&...&&, to call a subtemplate based on the value of an entry in the data array.
  • Conditional access with ??...??, to show a piece of HTML based on the existance or value of an entry in the data array.
  • Loops access with @@...@@, to repeat a piece of HTML based on a table of values.
  • Debug tools with !!...!!, to show the data array.

II. Reference


2.1. Comments


You may use comments into your template.
The comments will be discarded immediatly at the compilation of the template and not interfere with the rest of your code.

Comments are defined by %-- and --%

Example:



%-- This is a comment. It will not appear in the final code. --%

%--
This subtemplate will not be compiled, usable or even visible since it is into a comment
[[templateid]]
Anything here
[[]]
--%




2.2. Nested Templates


You can define new nested templates into your main template
A nested template is defined by:


[[templateid]]
your nested template
[[]]


The id is any combination of letters (a-z, A-Z, accents are welcome too), numbers (0-9), and 3 special chars: .-_

The old syntax also work and is deprecated. It will be definitively removed as of beginning of 2013.


%%SUBTEMPLATE(templateid)%%
your nested template
%%ENDSUBTEMPLATE%%


There is no limits into nesting templates.
Any nested template will inheritate all the father elements and can use father elements too.

Example:


&&header&&
Welcome to my page
&&footer&&

[[header]]


[[]]

[[footer]]


&©right&&

[[copyright]]
© 2012 Ing. Philippe Thomassigny, a project of the WebAbility® Network.
[[]]

[[]]



You may use more than one id into the same template to avoid repetition of the same code.
The different id's are separated with a pipe |


[[templateid|anotherid|something.key|andmoreid]]
your nested template
[[]]





2.3. Elements


The DomCore template system is based on a parameters replacement and a simple macrolanguage keywords.
Note: The syntax of the parameters, languages and fields is only recommended. However, any character combination may be replaced by the template engine.

The elements are replaced by the addElement() method into the template class.

We "logically" define 3 type of elements. The separation is only for human logic. The system doesn't make a difference between them. Anything you give to the method will be replaced, however the syntax is. You may define new syntax and new types of elements at will.
The official elements defined for the templates are:

  • parameters, which are any piece of information, generaly used to build the HTML code.
  • language entries, which are any readable information in the language you choose.
  • field values, which are generally usefull information from a database or data repository.

We highly recommend to use the metaelements instead of simple elements.


2.3.1. Parameters replacement:


Parameters generally have the following syntax: __PARAMETER__
They usually carry pieces of HTML code, for example a color, a size, a tag.

Example:



Welcome to my page.

You may use the same parameter as many time you wish.


Click me!
Click me again!





2.3.2. Languages entries


All the languages entries should have the format: ##entry##
A language entry is generally anything written into your page that does not come from a database, and should adapt to the language of the client visiting your site.
Using the languages entries may depend on the internationalization of your page.
If your page is going to be in a single language forever, you really dont need to use languages entries.
The languages entries generally carry titles, menu options, tables headers etc.

Example:



##welcome##

You may use the same parameter as many time you wish.


##clickme##!
##clickme## ##again##!





2.3.3. Field values


Fields values should have the format: {fieldname}
Your fields source can be a database or any other prefered repository data source.
Is it highly recomended to use this syntax for any data field you need to replace in your template.

Example:



Welcome to my site

You may use the same parameter as many time you wish.


Today's temperature is {degres} celsius

or {fdegres} farenheit


Is {degres} degres too cold ? Buy a pullover!






2.4. MetaElements


The metaelements are the recommended way to use with the templates.
They consist into an injection of an associative array of values, called the data array, into the template.
The macrolanguage is directly applied on the structure of the data array.

The data array is a nested set of variables and values with the structure you want (there is no construction rules).

You can inject nearly anything into a template metaelements.

Example of a data array to inject:


$array = array(
'detail' => array(
'key1' => array('name' => 'Juan', 'status' => 1),
'key2' => array('name' => 'José', 'status' => 2),
'key3' => array('name' => 'Pedro', 'status' => 3),
'key4' => array('name' => 'Phil', 'status' => 1),
'key5' => array('name' => 'Patrick', 'status' => 2),
),
'param1' => 'blue',
'param2' => 'red',
'param3' => '45px',
'param4' => '100%',
);



- The data array can be any traversable, iterable, countable object too, as of version 1.01.11 and superior.

- You can access directly any data into the array with its relative path (relative to the level you are when the metaelements are applied, see below).

- There are 5 metaelements in the DomCore templates to use the data array:
Data, Reference, Loops, Condition and Debug.

The structure of the metaelements in the template must follow the structure of the data array.

2.4.1. ID access: id


The id is 'a-z', 'A-Z', '0-9' and special chars '.-_'
If you use any other character for the id, the compiler will not recognize the keyword as an id and will surely generate errors.

2.4.2. Scope:


When you use an id to point a value, the template will first search into the available ids of the local level.
If no id is found, the it will search into the upper levers if any

Example:

$array = array(
'detail' => array(
'data1' => array(
'data2' => array(
'key1' => array('appname' => 'Nested App', 'name' => 'Juan', 'status' => 1),
'key2' => array('name' => 'José', 'status' => 2),
'appname' => 'DomCore'
)
)
)
);


At the level of 'data2', using {{appname}} will get back 'DomCore'
At the level of 'key1', using {{appname}} will get back 'Nested App'
At the level of 'key2', using {{appname}} will get back 'DomCore'
At the level of 'data1', using {{appname}} will get back an empty string





2.4.3. Path access: id>id>id>id


At any level into the data array, you can access any entry into the subset array.

For instance, if you have the following data array:


$array = array(
'detail' => array(
'data1' => array(
'data2' => array(
'key1' => array('name' => 'Juan', 'status' => 1),
'key2' => array('name' => 'José', 'status' => 2)
)
)
)
);



Let's suppose we are into a nested metaelements at the 'data1' level. You may want to access directly the 'Juan' entry.
The path will be:

data2>key1>name

The José's status value from the root will be:

detail>data1>data2>key2>status



2.4.4. Data: {{id}}


The data entries are accesible through a macrolanguage keyword: {{id}}

The template can work with a strict mode (elements are accesible only with the {{..}} syntax).
or in relax mode (any parameter name into the data array will be replaced, which is dangerous since you tend to use standard word to create variable names).

By default as of version 1.01.11, the default mode is strict

The id can be a direct name, or a path.

Example:
The two last nested metaelements at the 'data1' level will be:

{{data2>key1>name}} to access the 'Juan' entry from the 'data1' level.

The José's status value from the root will be:

{{detail>data1>data2>key2>status}}



2.4.5. References: &&id&& and &&id:templateid&&


Makes a call to a sub template and replace the &&...&& with the result.

If you use &&id&&, this is equivalent to &&id:id&&

The templateid is the id of the [[templateid]] to use.
The id is the variable id in the valors vector to inject in the template.
If the id exists in the valors vector, then its value is used to replace elements into the subtemplate.
If the id does not exists, then the subtemplate will be resolved only with the main template elements.

The id can be a direct name, or a path to access a data into the data array.


Example:


Our vector of values:
$array = array(
'image' => array('src' => '/pics/logo.gif', 'title' => 'Title of my image')
);


The template: (strict mode)

&&header&&
&&image:body&&
&&footer&&

using {{src}} and {{title}} out of the body template is useless, since they are into the {{image}} vector, thus to be used into the 'body' template.

[[header]]
Data header

[[]]

[[body]]

[[]]

[[footer]]

Data footer
[[]]




2.4.6. Loops: @@entry@@ @@entry:template@@ and @@entry:template:check@@


Makes a call to a subtemplate for each value in the loop vector (like the values of a table).

If you use @@entry@@, this is equivalent to @@entry:entry:@@
If you use @@entry:templateid@@, this is equivalent to @@entry:templateid:@@

If 'entry' does not exists in the values vector, or is empty, or is not a vector, the templateid with suffix '.none' will be searched.
If this template does not exists, nothing will be shown.

If 'entry' is a vector the following templates will be searched for each line, in that order:
- templateid.key.[value] value is the key of the vector line
- templateid.sel.[value] value is the value of the check field if it is defined and existing in the vector line
- templateid.first if it is the first element of the array set (new from v1.01.11)
- templateid.loopalt if the line number is even
- templateid.loop
- templateid

The entry and check can be a direct name, or a path to access a data into the data array.


Example:


Our vector of values:
$array = array(
'detail' => array(
'key1' => array('name' => 'Juan', 'status' => 1),
'key2' => array('name' => 'José', 'status' => 2),
'key3' => array('name' => 'Pedro', 'status' => 1),
'key4' => array('name' => 'Phil', 'status' => 1),
'key5' => array('name' => 'Patrick', 'status' => 2),
)
);

The template:

Here comes the loop:

@@detail:eachname:status@@

[[eachname.none]]
There is nobody in the list

[[]]

%-- First element --%
[[eachname.first]]
Default user:
Name: {{name}}, Status: {{status}}


[[]]

%-- Number 2 is special --%
[[eachname.sel.key2]]
Name: {{name}}, Status: {{status}}

[[]]

[[eachname]]
Name: {{name}}, Status: {{status}}

[[]]


Another way to show the data:

@@detail@@

[[detail.none]]
There is nobody in the list

[[]]

[[detail.loopalt]]
Name: {{name}}, Status: ??{{status}}:status??

[[status.2]]Fired[[]]
[[status]]Ok[[]]
[[]]

[[detail.loop]]
Name: {{name}}, Status: ??{{status}}:status??

[[status.2]]Fired[[]]
[[status]]Ok[[]]
[[]]




2.4.7. Conditional: ??entry?? ??entry:templateid?? and ??entry:templateid:check??


Makes a call to a subtemplate only if the field exists and have a value.

If you use ??entry??, this is equivalent to ??entry:entry:??
If you use ??entry:templateid??, this is equivalent to ??entry:templateid:??

If 'entry' does not exists in the values vector, or is empty, or is not a vector, the templateid with suffix '.none' will be searched.
If this template does not exists, nothing will be shown.

The template with the suffix .none is mandatory.

If 'entry' is a vector the following templates will be searched, in that order:
- templateid.[value] value is the value of the check field if it is defined and existing in the vector line
- templateid

The entry and check can be a direct name, or a path to access a data into the data array.

Example:


Our vector of values:
$array = array(
'image1' => null,
'image2' => array('src' => '/pics/logo.gif', 'title' => 'Title of the image')
'image3' => array('src' => '/pics/logo.gif', 'title' => 'Another title of the image', 'status' => 1)
);

The template:

??image1:image:status??
??image2:image:status??
??image3:image:status??

[[image.none]][[]]

[[image.1]]
Image with status=1:

{{title}}

[[]]

[[image]]
{{title}}

[[]]




2.4.8. Debug tools


There are two keywords to dump the content of the vector of values, i.e. the elements and the metaelements.
This is very usefull when you dont know the code that calls the template, don't remember some values, or for debug facilities.

2.4.8.1. !!dump!!

Shows the totality of the elements and metaelements, variables and values.

2.4.8.2. !!list!!

Shows only the variables names of the elements and metaelements, values are not shown.


III. How to use the templates classes


There are two classes to use templates and templates files:


If you want to control the source and code of your template, you may use \core\WATemplate, injecting it the template code.
\core\WATemplate will compile and keep the compiled template in memory untill you need it to generate your final code.

How to use it:


  • Load the template file:

$buffer = file_get_contents('path/to/your/file.template');


  • Create the template object with your template file string:

$template = new \core\WATemplate($buffer);


  • Inject elements and metaelements in the template object:

$template->addElement('variable', 'value');
$template->addElements(array('variable' => 'value'));
$template->metaElements(array('variable' => 'value'));


  • Resolve the template to get the generated code:

print $template->resolve();
// similar to
print $template;



If you want to use caches and compiled files for much faster access (for instance if you use it in a CMS or so), it is better to use TemplateSource since it resolve all the caches workflow, up to stock the template in shared memory.

How to use it:


  • Create the template source:

$SHM = new \core\WASHM(); // Do no forget to use a unique ID for your application
$templatesource = new \datasources\TemplateSource(
new \datasources\FileSource('base/path/', 'local/path/', 'your_template_file.template'),
new \datasources\FastObjectSource(
new \datasources\FileSource('base/path/', 'local/path/', 'your_afo_file.afo'),
new \datasources\SHMSource('unique_memory_id', $SHM)
)
);


  • Use the template source to retrieve the template object:

$template = $templatesource->read();


  • Inject elements and metaelements in the template object:

$template->addElement('variable', 'value');
$template->addElements(array('variable' => 'value'));
// Same as
$template->metaElements(array('variable' => 'value'));


  • Resolve the template to get the generated code:

print $template->resolve();
// Similar to
print $template;



As a reference, using the simple \core\WATemplate object will take approx 12 milisecond to load/compile/resolve the template.
Using the shared memory cache will take only 2 milliseconds to get the template and resolve it (on a 2GHz Xeon processor).

Talking about a good CMS or an application with many templates, using the \datasources\TemplateSource decreases dramatically file accesses and calculation time of your code.