Parameters of the in-browser templating engine appear in a data block script element in the document (or shadow DOM if it's a component).
<script type="text/json" id="templating-program">[ /*here is the main program*/ ]</script>
The top of the structure (the main program) is an array of the following kinds of elements.
(1) For an HTML/templating element with quantifiers in the bracy template document: Instantiation Instruction object,
{
"calculate": [
[ "name1", ... ], /*for explanation, see wiki page "Calculate Language"*/
... /*one array for each placeholder in the tag (not counting in the attribute value)*/
]
"template": "{template-id}", /*the ID of the <template> that needs to be instantiated, according to the result*/
"assign": { "name": [ "name1", ... ], ... }, /* declares new names in the scope of the subprogram below */
"sub": [ /*the same structure as the main program*/ ],
/*count limits; omit both fields if t:times="0+"*/
"min": 1, /*if t:times="1" or "1+"*/
"max": 1 /*if t:times="1" or "1-"*/
}
(2) for an HTML/templating element that has no quantifier but t:times attribute: Instantiation object with the "calculate" field omitted,
(3) for a text node (child or attribute value) in which one or more placeholders appear: Substitution Instruction object,
{
"context": "elem-id", /*subject to id translation if in a plural template*/
"xpath": "text()[1]", /*point to the text node; xpath is relative to the element with the id in "context" field*/
"parts": [ /*concatenate the following parts in order to get the text content to substitute*/
"prefix", /*elements that have a JSON type string are taken as a string literal*/
[ "name1", ... ], /*array typed element: take the result of operations; see wiki page "Calculate Language"*/
... /*alternate between string and array elements; parts field can start with any of the two types, and can end with any*/
],
"assign": { "name": [ "name1", ... ], ... }, /* declares new names in the scope of the subprogram below */
"sub": [ /*the same structure as the main program*/ ]
/*no need to define count limits here: if there are any, it appears in an Instantiation Instruction*/
}
The calculate language appears as a JSON array in the above structure in these possible places:
It is a transformed version of the series of operations in the [Placeholders].
See [Calculate Language].
In the sub field of the structure, the format of the top level array is repeated. The subprogram will have a narrower scope: if the calculate results in a collection of objects, the fields of that object can be accessed by name in this scope.
See [Examples (Templating Program)] page.
The template engine in theory could evaluate any XPath, however the transplate script will simply select one from the following XPaths:
"."t:times="0+" or "1+"), ID needs to depend on (contain) the counter"text()""text()[1]""@attr""following-sibling::text()[1]"[2] or higherElement node can be identified by id attribute. Attribute values can be replaced as a whole. Inner text nodes are trickier. In between sibling text nodes, elements may appear and even multiply due to templating.
Solution: set the ID of the preceding element, or, if none, the parent. It would be logical to keep the template itself behind all its own instantiated elements. It would have its ID so the following text node would be findable. At the same time, it keeps track where to add new instances of the template. Locators would be XPaths evaluated by documentFragment.evaluate calls.
If there is an element with an ID attribute in the template, the in-browser template engine needs to give those elements new unique IDs before it instantiates more than one instance. The in-browser template engine needs to do the substitutions using the original IDs since the progam references those. When the substituted value is Observable then it subscribes at the Observable such a callback that updates the text node located via the new ID.
In templates that are t:times="1-" or "1", the translation is identity, i.e. the IDs don't change.
Note: not only the transplate script needs an IdFactory instance but also the in-browser template engine. The class goes to the common module.
Note: the ID attributes should not accept an Observable value.
The in-browser templating engine can expect a node to be filled with data to be found using one of the following JavaScript snippet. In the DOM:
document.evaluate(xpath, document.getElementById(id), null, 8).singleNodeValue.nodeValue = calculationResult
The in-browser templating engine can expect the templating program data block to be found using the following JavaScript snippet.
const prg = JSON.parse(document.getElementById("templating-program").text)
Wiki: Calculate Language
Wiki: Examples (Templating Program)
Wiki: Home
Wiki: Placeholders