Skip to content

Templater

Eric edited this page Mar 24, 2024 · 79 revisions

OGX.JS contains its own templating engine, OGX.Templater crafted into a separate component that is used by more than one component (OGX.DynamicList, OGX.GroupedList...). It can also be used on demand to render templatized objects.

Templates can be stored and then pre-loaded and accessible throughout the app, by settings them in app.json. Check out this page for more info about preloading.

 "preload": {
      "/html": [
       ... your files here
       ]
 }

Note that this is automatic with the CLI, using ogx create template TEMPLATE_NAME

Consider the following list of objects

 let array = [
      {age:20, age_hidden:false, name:'Paul', home:{state:'ON'}}, 
      {age:50, age_hidden:true, name:'Gillian', home:{state:'BC'}}
 ];

Templating an object

 let html = OGX.Templater.make(_STRING_, _OBJECT_);

Since 1.8.0 the templatize has been deprecated and replaced by make

Simple echo

To simply output the value of a property, do

 {{$property}}

so, to replace the properties in a template with the actual values of an object, do

 let template = '<span>{{$name}}</span><span>{{$age}}</span><span>{{$home.state}}</span>';
 let html = OGX.Templater.make(template, array[0]);

html becomes

 <span>Paul</span><span>20</span><span>ON</span>

Templating operations

OGX.JS templating system uses OSE as scripting engine. Check out the OSE page dedicated to it

  {{OSE expression}}

For instance

  {{$age > 30 ? $css="grey" : $css="blue"}}

means if the age property of the object is bigger than 30, set (or create) a property css on my object and give it a value of "grey". Then add the value of the property css inside the class attribute. Which would give, once the object is templatized:

 let html = OGX.Templater.make(template, array[0]); 

result

 <div class="user blue"><span class="age">20</span></div>

other example

 let html = OGX.Templater.make(template, array[0]); 

result

 <div class="user grey"><span class="age">50</span></div>

In the following example, we create a new property dage that takes and displays the value of the property age if the property age_hidden is not set to true.

 let template = '<span class="name">{{$name}}</span><span class="age">{{$age_hidden===true?$dage="":$dage=$age}}{{$dage}}</span>';

 let html = OGX.Templater.make(template, array[0]); 

 //result
 <span class="name">Paul</span><span class="age">20</span>

 let html = OGX.Templater.make(template, array[1]); 

 //result
 <span class="name">Gillian</span><span class="age"></span>

Note that in this case, we create a new property dage onto our original object. If you wish to keep your original object intact, use @ (see Using $ vs @ bellow)

It is also possible to use custom functions within a template to extend the data manipulation capabilities of the component. Consider the following function to add decimal to a number

 function addDec(__num){
      return parseFloat(Math.round(__num*100)/100).toFixed(2);
 }

To apply this function inside a template (to add decimals to a common property)

 let array = [{price:10}];
 let template = '<span class="price">{{$price=addDec($price)}}{{$$price}}</span>';

Would result in

 <span class="price">$10.00</span>

Using $ vs @

OGX.Templater allows to create on the fly some properties as a result of a OSE expression, but there is a difference between $ and @:

$ means that the property will be set over the original object that you pass, but @ will be set over a temporary object, only used for calculations and display.

Consider the following OSE expression where we'd like to hide the display of the age of a person if it's higher than 30, but we do not want to alter our source object and overwrite the property, instead, we want to use a temporary object to store the calculated value.

 {{$age > 30 ? @age= '' : @age = $age}}

Here we have set over a temporary object, the property age using @. This means that we will be echoing this temporary property instead of the real property of the object, by doing

 {{@age}}

Using #

You can also reference global variables, in the case, you must put # in front of your object. For instance, if you have a globally declared user, and want to output first_name, you would do

{{#user.first_name}}

(Not) Using &

It's very important to note that variable starting with & are reserved by OML to point to a previous object of the tree. Therefor it does not work inside a template.

Templating recursive

Starting at version 1.17.0, you can compose the inner html of a template with another template while using another object, using OSE

 {{template STRING|VARIABLE PATH_TO_OBJECT}}
 {{template $type $sub_object}}
 {{template article #article}}

Templating a JSON document

Starting at version 1.8.2 it is also possible to replace variables and objects inside a JSON object. The only supported operator is $

  const html = OGX.Templater.jmake(JSON_OBJECT, OBJECT);

Templating multiple objects at once

Starting at version 1.24.0, you can templatize multiple objects are once. This is an alternative to using the OSE loop or using a DynamicList for static content.

  const html = OGX.Templater.amake(JSON_OBJECT, ARRAY_OF_OBJECTS);

Debugging

OGX.Templater make method accepts a third parameter that is set to false by default. If you set it to true, the templater will not remove failed echos, failed operations and failed loops.

Preloading and Storing

You can also preload your HTML templates and get them as you need. All templates must be stored by name such as

 OGX.Templater.loadTemplates([{name:'templateA', file:'/path/to/fileA.html'}, {name:'templateB', file:'/path/to/fileB.html'}]);

And you can listen for loaded templates one by one

 $(document).on(OGX.Templater.TEMPLATE_LOADED, function(__event, __object){
      //__object.name = name of the template
      //__object.html = html as string
 });

Or when they're all loaded

  $(document).on(OGX.Templater.TEMPLATES_LOADED, function(__event){
       //Simple event, no data
  });

You can also use a callback instead of an event, such as

 OGX.Templater.loadTemplates([{name:'templateA', file:'/path/to/fileA.html'}, {name:'templateB', file:'/path/to/fileB.html'}], onTemplatesLoaded);

 function onTemplatesLoaded(){
       //console.log('all loaded!');
 }

Since 1.8.0, To retrieve a template (as HTML string), do

 let template = OGX.Templater.get(__name);

Prior to 1.8.0 (deprecated)

 let template = OGX.Templater.getTemplate(__name);