Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/sviperll/static-mustache
Template engine for java with statically checked and compiled templates. Compilation is performed alone with java sources.
https://github.com/sviperll/static-mustache
java mustache template-engine type-safe
Last synced: 18 days ago
JSON representation
Template engine for java with statically checked and compiled templates. Compilation is performed alone with java sources.
- Host: GitHub
- URL: https://github.com/sviperll/static-mustache
- Owner: sviperll
- License: bsd-3-clause
- Created: 2014-12-05T16:17:03.000Z (almost 10 years ago)
- Default Branch: master
- Last Pushed: 2020-10-13T09:05:47.000Z (about 4 years ago)
- Last Synced: 2024-10-12T07:16:47.195Z (about 1 month ago)
- Topics: java, mustache, template-engine, type-safe
- Language: Java
- Homepage:
- Size: 150 KB
- Stars: 28
- Watchers: 5
- Forks: 4
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Static mustache
===============Logicless text templating engine.
Templates are compiled alone with Java-sources.
Value bindings are statically checked.Features
--------* Logicless templating language.
* [Mustache](http://mustache.github.io/) syntax.
* Templates are compiled into effective code
* Value bindings are statically checked.
* Methods, fields and getter-methods can be referenced in templates.
* Friendly error messages with context.
* Zero configuration. No plugins or tweaks are required.
Everything is done with standard javac with any IDE and/or build-system.* Non-HTML templates are supported. Set of supported formats is extensible.
* Layouts are supported, i. e. generation of header and footer from one template.
Installation
------------Use maven dependency:
```xml
com.github.sviperll
static-mustache
0.4
```Changelog
---------* Since 0.3
Switch to metachicory version 0.24. Replace text-formats dependency with chicory-text 0.24.
Add support for layouts, see `Html5Layout` example.* Since 0.2
Introduce metachicory 0.17 and text-formats 0.17 dependencies
Example
-------### user.mustache ###
```
{{#name}}Name: {{.}}, Name Length is {{length}}
{{/name}}Age: {{ age }}
Achievements:
- {{.}}
{{#array}}
{{/array}}
{{^array}}
No achievements
{{/array}}
Items:
- {{value}}
{{#list1}}
{{/list1}}
```
### User.java ###
Following class can be used to provide actual data to fill into above template.
```java
@GenerateRenderableAdapter(
// points to src/main/resources/user.mustache file
template = "user.mustache",
// adapterName can be omitted. "Renderable{{className}}Adapter" name is used by default
adapterName = "RenderableHtmlUserAdapter")
public class User {
final String name;
final int age;
final String[] array;
final List> list1;
public User(String name, int age, String[] array, List> list1) {
this.name = name;
this.age = age;
this.array = array;
this.list1 = list1;
}
public static class Item {
private final T value;
public Item(T value) {
this.value = value;
}
T value() {
return value;
}
}
}
```
### Rendering ###
New class `RenderableHtmlUserAdapter` will be mechanically generated with the above code. This class can be used to render template filled with actual data. To render template following code can be used:
```java
class Main {
public static void main(String[] args) throws IOException {
User user = new User("John Doe", 21, new String[] {"Knowns nothing"}, list);
Renderable renderable = new RenderableHtmlUserAdapter(user);
// Any appendable will do: StringBuilder, Writer, OutputStream
Renderer renderer = renderable.createRenderer(System.out);
// Write rendered template
renderer.render();
}
}
```
The result of running this code will be
```
Name: John Doe, Name Length is 8
Age: 21
Achievements:
- Knowns nothing
Items:
- helmet
- shower
```
Referencing non existent fields, or fields with non renderable type, all result in compile-time errors. These errors are reported at your project's compile-time alone with other possible errors in java sources.
```
target/classes/user.mustache:5: error: Field not found in current context: 'age1'
Age: {{ age1 }} ({{birthdate}})
^
symbol: mustache directive
location: mustache template
```
```
target/classes/user.mustache:5: error: Unable to render field: type error: Can't render data.birthdate expression of java.util.Date type
Age: {{ age }} ({{birthdate}})
^
symbol: mustache directive
location: mustache template
```
See `static-mustache-examples` project for more examples.
Design
------
The idea is to create templating engine combining [mustache](http://mustache.github.io/) logicless philosophy
with Java's single responsibility and static-typing.
Full compile-time check of syntax and data-binding is the main requirement.
Currently Java-code is generated for templates. Generated Java-code should never fail to compile.
If it is impossible to generate valid Java-code from some template,
friendly compile-time error pointing to template file should be generated.
Users should never be exposed to generated Java-code.
Original mustache uses Javascript-objects to define rendering context.
Fields of selected Javascript-objects are binded with template fields.
Static mustache uses Java-objects to define rendering context.
Binding of template fields is defined and checked at compile-time.
Missing fields are compile-time error.
Current differences from mustache
---------------------------------
* Lambdas are not supported
* Partials are not supported
* Delimiter redefinition is not supported
Interpretation of Java-types and values
---------------------------------------
See [original mustache manual](http://mustache.github.io/mustache.5.html).
When some value is null nothing is rendered for this mustache-variable or mustache-section anyway.
Boxed and unboxed booleans can be used for mustache-sections. Section is only rendered if value is true.
Arrays and Iterables can be used in mustache-sections and are treated like Javascript-arrays in original mustache.
Any non-null object can be used for mustache-section.
This object serves like a data-binding context for given section.
Data-binding contexts are nested.
Names are looked up in innermost context first.
If name is not found in current context, parent context is inspected.
This process continues up to root context.
In each rendering context name lookup is performed as following.
Lookup is performed in Java-class serving as a rendering context.
1. Method with requested name is looked up.
Method should have no arguments and should throw no checked exceptions.
If there is such method it is used to fetch actual data to render.
Compile-time error is raised if there is method with given name, but
it is not accessible, has parameters or throws checked exceptions.
2. Method with getter-name for requested name is looked up.
(For example, if 'age' is requested, 'getAge' method is looked up.)
Method should have no arguments and should throw no checked exceptions.
If there is such method it is used to fetch actual data to render.
Compile-time error is raised if there is method with such name, but
it is not accessible, has parameters or throws checked exceptions.
3. Field with requested name is looked up.
Compile-time error is raised if there is field with such name but it's not accessible.
4. Search continues in parent-context if all of the above failed.
Primitive types and strings can be used in mustache-variables.
Escaping is always performed for mustache-variables.
Unescaped variables are supported as in original mustache.
Any boxed or unboxed primitive type is rendered with toString method.
Strings are rendered as is.
Rendering of other Java-types as mustache-variable is currently compile-time error.
License
-------
Static mustache is under BSD 3-clause license.
Flattr
------
[![Flattr this git repo](http://api.flattr.com/button/flattr-badge-large.png)](https://flattr.com/submit/auto?user_id=sviperll&url=https%3A%2F%2Fgithub.com%2Fsviperll%2Fstatic-mustache&title=static-mustache&language=Java&tags=github&category=software)