All Downloads are FREE. Search and download functionalities are using the official Maven repository.

js.template.xhtml.package-info Maven / Gradle / Ivy

Go to download

Reference implementation for j(s)-lib template API, declarative, natural and based on X(HT)ML language.

The newest version!
/**
 * Declarative X(HT)ML templates engine. First thing first: declarative part. This templates engine is indeed declarative. It
 * does not embed programming language into (X)HTML code. And this - beside being much easier to learn and use - comes with important 
 * consequence: a complete separation of logic and data. Declarative nature forces view to deal only with presentation, there is no 
 * chance for developer to mix-in business logic - see code samples.
 * 
 *  <ul data-list="contacts">
 *      <li><span data-text="name" /> - <span data-text="phone" /></li>
 *  </ul>
 * 
* Below is a typical templates engine using embedded Groovy. For a user interface developer seasoned with HTML this code may * look a little more difficult to grasp. But the real thing is concern separation: user interface developer need not to know contacts * comes from an instance named client and that field name is contact. And because the language allows it, is * possible to alter model object values from templates which is bad. *
 *  <ul>
 *  #{list contacts:client.contacts, as:'contact'}
 *      <li>${contact.name} - ${contact.phone}</li>
 *  #{/list}
 *  </ul>
 * 
* *
    *
  1. natural template *
  2. strict separation of view from business logic *
  3. simple syntax that can be understood by graphic designers *
* *

Temples engine overview

* A template is an X(HT)ML file that contains templates operators. An operator is declared * into and operates on an {@link js.dom.Element} and has an opcode and exactly one operand. The most common operator is * setter which takes care to set element text content or attribute. A short example may clarify: *
 *  // model object
 *  class Person {
 *      String description = "person description";
 *      Picture picture = new Picture("images/person.png");
 *  };
 *  
 *  // template fragment
 *  <p data-text="description"></p>
 *  <img data-attr="src:picture;title:description;" />
 * 
* Templates engine enacts data-text and data-attr operators that set paragraph text to Person * description, image source to picture and image tooltip, i.e. its title attribute, also to description. *
 *  <p>person description</p>
 *  <img src="images/person.png" title="person description" />
 * 
* * Templates operators are declared using standard X(HT)ML attributes and uses next syntax: *
 *  operator := 'data' '-' opcode '=' '"' operand '"'
 *  opcode := see operators list
 *  operand := propertyPath | expression
 *  propertyPath := see object property path 
 *  expression := evaluated by operator
 * 
* One may notice operator opcode is prefixed with data-. This is indeed on purpose: HTML5 allows for element attributes * extensions and extensions name start exactly with that prefix. *

* Since instruction syntax is a subset of supporting template syntax it can be kept into resulting document. This comes with a * big advantage: the same instructions can be used to extract model object from documents generated by templates processor. * This can be seen as an object oriented alternative to micro-formats. So templates processor can be used for both injection * and extraction of the model object into/from documents. *

* When processing templates, the DOM tree is traversed in synchro with model object graph. DOM is a tree of elements and * model is a tree of values; model tree is mapped on elements tree. This does necessarily means those trees are congruent, elements * tree can and usually is more complex but its overall structure resemble model tree. * *

 *                   e1 
 *                  /               
 *     m1          e   
 *    /           / \ 
 *  m0          e0   e
 *    \           \    
 *     m2          \  
 *                  e2 
 * 
* * Templates engine define a function TE: m -> e defined on model with values on elements, in other words model is domain whereas * elements tree is codomain. Note that TE is not surjective, that is, not for every element e in the codomain there * is an m in the domain such that TE(m) = e. * *

Templates operators list

* Templates engine algorithm is generic and operates on operator types, that is, groups of operators. This way adding new operators * does not require algorithm update. This operators list is displayed using that types hierarchy. *

*

* * * * * * * * * * * * * * * * * * * * * * * * *
1. CONDITIONAL - include or exclude DOM branches based on some condition: *
{@link js.template.xhtml.IfOperator if} * if value is empty element branch is not included in resulting document *
{@link js.template.xhtml.ExcludeOperator exclude} * exclude element and its descendants from resulting document; implementation may choose to hide or completely remove the branch * *
  *
2. ATTRIBUTE - set specified attribute to value extracted from content: *
{@link js.template.xhtml.AttrOperator attr} * set attributes values; both attributes name and value are specified into expression operand *
{@link js.template.xhtml.IdOperator id} * convenient attribute setter for element ID *
{@link js.template.xhtml.SrcOperator src} * convenient attribute setter for image source *
{@link js.template.xhtml.HrefOperator href} * convenient attribute setter for hyper-references; element should be an anchor or a resource link *
{@link js.template.xhtml.TitleOperator title} * convenient attribute setter for tooltips *
{@link js.template.xhtml.ValueOperator value} * convenient attribute setter for element value; element should be an input or textarea * *
  *
3. CONTENT - operates upon element content be it text content or generated children elements: *
{@link js.template.xhtml.ObjectOperator object} * current element is an object with many properties and should have child elements *
{@link js.template.xhtml.TextOperator text} * set element text content *
{@link js.template.xhtml.HtmlOperator html} * set element inner HTML, useful for text formatted with HTML tags *
{@link js.template.xhtml.NumberingOperator numbering} * set element text content accordingly numbering format and item index *
{@link js.template.xhtml.ListOperator list} * current element is a list and should have a child element that is processed as list item *
{@link js.template.xhtml.OListOperator olist} * ordered variant of {@link js.template.xhtml.Opcode#LIST}, that is, list with numbering *
{@link js.template.xhtml.MapOperator map} * current element is a map and should have two child elements: first processed as map key and the second as value *
{@link js.template.xhtml.OMapOperator omap} * ordered variant of {@link js.template.xhtml.Opcode#MAP}, that is, map with numbering * *
  *
4. FORMATTING - set format instance used to prepare content value before actual insertion: *
{@link js.template.xhtml.FormatOperator format} * set formatter for value and text content setters *
*

* Operators precedence is controller by their types in next order: conditional, inline, attribute, content and scope operators. *

Object property path

* Basically templates operators inject values from content into target document. In order to identify the right * piece of information content is regarded as a tree of values; every value can be reached traversing the three, * from node to node following a unique path. *
 *  class Person {
 *      String name;
 *      Address address {
 *          Locality locality {
 *              String name;
 *          }
 *      }
 *  }
 * 
* In above pseudo-code person and locality names are values; locality name path is .address.locality.name whereas person * name is simple .name. Both exemplified paths starts with dot, meaning they are absolute path. Is also possible to use * relative paths, but we need a reference named scope object or simply scope. So, if scope is Address, locality name path * is locality.name; note missing dot from path start. For this reason all operators receive a scope object into parameters * list. Also, template scanning starts with scope root, in our case Person instance; there is a scope operator used to change current scope. * *

Templates implementations

* There are two templates engine implementations: serializer and injector. A serializer traverses DOM tree using * depth-first algorithm and serialize every node to a given writer. If current node contains templates operators * execute them. Operator execution act upon model object and result is also serialized to stream. *
 *  TEMPLATE -> DOM -> TP -> WRITER
 *                      ^
 *                      |
 *                   CONTENT
 * 
* An injector templates engine also traverses source DOM using depth-first but model object values are injected directly into * source DOM, altering it. *
                  
 *               |<-----|       
 *               v      |  
 *  TEMPLATE -> DOM -> TP
 *                      ^
 *                      |
 *                   CONTENT   
 * 
* Currently server side implementation is a serializer and client side is an injector for obvious rationales: server should send back * to client documents generated on the fly, serialized on Servlet writer whereas client side should update loaded DOM in order to update * user interface. But both support the same operators with exactly the same behavior so that documents generated on server side or on * client look exactly the same, of course if generated from the same template. * * *

Experimental Solution

* Uses namespace for operators prefix and o:load operator to load content from server. *
 *  <tr xmlns:o="http://js-lib.com/dom" o:load="/rest/contradiction">
 *      <td><img o:src="image" o:title="name" /></td>
 *      <td o:object="tasks.0" o:css-class="tasks.0:active">
 *          <p o:text="start" o:format="js.format.StandardDateTime"></p>
 *  . . .    
 * 
* * @author Iulian Rotaru * @version 1.0 */ package js.template.xhtml;




© 2015 - 2025 Weber Informatics LLC | Privacy Policy