The Java Template Engine (jte) is a secure and lightweight template engine designed for Java and Kotlin applications. It emphasizes minimal syntax, leveraging existing language features to make templates intuitive and maintainable.
Create a template in jte directory with extension of .jte.
template - index.jte in src/main/jte
@param String name // for parameters from model map
<!DOCTYPE html>
<html>
<head>
<title>Hello JTE</title>
</head>
<body>
<h1>Hello, ${name}!</h1>
</body>
</html>
To view this on browser we need to create a controller also
@Controller
public class HomeController {
@GetMapping("/")
public String home(Model model) {
model.addAttribute("name", "Dan"); // sending name parameter to jte
return "index";
}
}
Properties available for JTE
# determine the jte template locations
gg.jte.templateLocation=src/main/jte # default is same
# configure template suffix
gg.jte.templateSuffix=.jte # default is same
# precompile the templates for faster startup and rendering, recommended in prod
gg.jte.usePrecompiledTemplates=true #dafault is false
# used for development as watcher will watch for changes in templates and recompile them
gg.jte.developmentMode=true
Template Syntax
${}
To display data from variable , can be used with general data types along with Any class implementing gg.jte.Content
<%-- ... --%>
To display comments
@import
Used to import direcly from app like classes, records etc.
Need to use fully qualified name e.g. @import com.app.Sample
@Param
It used to declare the parameter that is passed to this template. e.g. @param Sample sample
The datatype could be premitive or the custom dto , models or records etc.
For any classes we need to either import them first or need to use fully qualified name with @param.
we can also assign default values
@if/@endif
Used for flow control in the template
for nesting we can also use @elseif
@for and @endfor
Used to loop over variable
loop can be both fori or for in
we can also use @else with for , as in case of no data else part will get executed.
!{}
used to declare local variable
that can be used with ${}
Content
gg.jte.Content is a special parameter type, that is used to pass template code to other templates, much like lambdas in Java.
They are handy for sharing structures between different templates.
Example -
@import org.example.Page # imports custom class
@import gg.jte.Content # imports content
@import my.Model
@param Page page
@param Content content
@param Content footer = null # asigning default value
@param String param;
@param Model model
@param Task task
<title>${param}</title>
<head>
@if(page.getDescription() != null)
<meta name="description" content="${page.getDescription()}">
@endif
<title>${page.getTitle()}</title>
</head>
<body>
<h1>${page.getTitle()}</h1>
<%-- if else --%>
@if(model.entries.isEmpty())
<p>I have no entries!</p>
@elseif(model.entries.size() == 1)
<p>I have one entry!</p>
@else
<p>I have ${model.entries.size()} entries!</p>
@endif
## looping
@for(var entry : model.entries)
<li>${entry.title}</li>
@endfor
@for(int i = 0; i < 10; ++i)
<li>i is ${i}</li>
@endfor
## variable
!{var innerObject = someObject.get().very().deeply().located().internal().object();}
${innerObject.a()}
${innerObject.b()}
<div class="content">
${content}
</div>
@if (footer != null)
<div class="footer">
${footer}
</div>
@endif
<%-- importing other templte --%>
@for(Task task : tasks)
@template.task-row(task = task)
@endfor
</body>