Templating Web
Templating Web
Everit Web Templating can be used to render web pages based on HTML templates. The library can also be used to generate XMLs as XML syntax is compatible with HTML.
The goals of the templating engine are:
// Get a template from somewhere (e.g.: from a file) String text = ""; // Instantiate any expression compiler (e.g.: MVEL) ExpressionCompiler expressionCompiler = new MvelExpressionCompiler(); // Instantiate template compiler and pass the expression compiler HTMLTemplateCompiler compiler = new HTMLTemplateCompiler(expressionCompiler); // Get a classloader that can be used to compile the template if necessary ClassLoader cl = this.getClass().getClassLoader(); // Instantiate a ParserConfiguration ParserConfiguration configuration = new ParserConfiguration(cl); // Compile the template CompiledTemplate template = compiler.compile(text, configuration); ///////////////////////////////////////////////////////////////////////// // Rendering the template ///////////////////////////////////////////////////////////////////////// // Create a map for the variables that can be used within the template Mapvars = new HashMap<>(); vars.put("name", "John Doe"); // Get a Writer from somewhere (e.g.: a ResponseWriter or a StringWriter Writer writer = new StringWriter(); // Render the template to the writer template.render(writer, vars); // In this example we write out the result to the standard output System.out.println(writer.toString());
Iterates through the elements of an Iterable element, Object array or primitive array. The value of the attribute must be a Map where the key is the name of the variable that holds the element of the iteration, the value holds the collection that is iterated. Example based on MVEL:
John | Doe |
An array of two Strings can be defined as the key of the Map. In that case the first element of the array will show the name of the variable of the element, while the second String will be the name of the index variable. Example based on MVEL expressions:
1 | John | Doe |
Multi-iteration is also supported when the Map has more entries. Use this only if you are sure that the Map keeps its insertion order, otherwise the output might be "randomized".
It is possible to run a code block. In most cases it is necessary to declare new variables.
The code snippet above will write out
Sometimes it is not possible to declare variables with the expression language that are put into the variables map. That is where var helps.
With var it is possible to declare / assigne one or more variables. The value of the attribute must be a Map, where the keys of the Map are the name of the variables and the values of the Map are the values of the variables. Example based on MVEL:
...
A case-insensitive String value that tells which parts of the element should be rendered:
Boolean values can also be used in the following way:
The value of the render attribute can be defined dynamically:
...
In case none is specified as a constant, the parsing of the element and its content is skipped completely. This is useful if we want to comment something out from the template in the way that it is not processed:
...
Replaces the content of the element with the result of the evaluation of the value of the attribute. The text will be escaped.
John
This attribute should be used also if the content of the tag is written with a function call directly to the writer. E.g.:
John
In the example above, the writeOnWriter might be a void function that writes onto the same writer that is passed to the CompiledTemplate.render(...) function.
Same as text, but the text will not be escaped.
A Map of attribute overrides.
The output of the template above will be the following:
It possible to override the value of any attribute by defining a new value.
Prepends the value of one or more attributes. A Map should be provided where the keys are the name of the attributes and the values of the Map are the new values.
The output of the template above will be the following:
As with attr-*, it is possible to prepend attributes. A String should be provided!
The output of the template above will be the following:
Same as attrPrepend, but it appends the newly defined values to the end of the original attributes.
Same as attrprepend-*, but it appends the newly defined value to the end of the original attribute.
It is possible to mix the syntax of the template with other template syntaxes. This is useful if some other format should be embedded whithin a template, e.g.: a javascript.
Inline template compilers must be defined during the initialization of the HTML template compiler.
// Instantiate any expression compiler (e.g.: MVEL) ExpressionCompiler expressionCompiler = new MvelExpressionCompiler(); // Create the inline compilers and put them into a Map TemplateCompiler textCompiler = new TextTemplateCompiler(expressionCompiler); MapinlineCompilers = new HashMap<>(); inlineCompilers.put("text", textCompiler); // Instantiate template compiler and pass the expression compiler HTMLTemplateCompiler compiler = new HTMLTemplateCompiler(expressionCompiler); // Compile and render the template...
In the example above one inline compiler was defined with the text identifier. In the template the same identifier should be used within the fragment attribute as a constant String.
It is possible to define fragments that can be rendered separately, too.
This is the content of the fragment
The fragment can be rendered programmatically:
template.render(writer, vars, "myFragment");
It is also possible to render a fragment from any place of the template that defined it:
Let's say that a fragment should be rendered only if it is called:
This is the content of the fragment
By default data-eht- is the prefix for the templating attributes. This is good for HTML as in HTML any attribute starting with data- are allowed.
However, in XML someone might wants to use an XML namespace instead. The default prefix can be overridde in the constructor of HTMLTemplateCompiler.
new HTMLTemplateCompiler(expressionCompiler, inlineCompilers, "eht:");
In the XML, the namespace can be defined with the prefix above. In case the namespace definition should be hidden in the output, it can be deleted by overriding the value of the namespace declaration to null with the attr attribute.
....
Web Templating can be used to generate XML documents as XML has stricter rules than HTML.
// TODO example of using custom namespace.
In XML all tags must be closed. However, in HTML the same rules are not applied, it is possible to use a tag without closing it. E.g.:
MyText
Everit HTML templating is often 7-10x faster than concurrent templating engines. The test1.html template that is located in the src/main/resources folder, can be rendered more than 30 times in a millisecond on a Core i5 CPU.
Exact benchmarks will come later, but if you are impatient, you can run one by yourself and share it on the wiki page.