The following is a standalone Thymeleaf demo (no web application needed; no Spring used):
Assumptions:
I have a messages file called test.properties
containing the following:
test.message=This is a message to you.
I have a related HTML template called test.html
:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<p th:text="#{test.message}">This is a report</p>
<p th:text="${note}">This is a note</p>
</html>
In the above template, I added Thymeleaf variable expression (${note}
), as well as the message expression - just to make the demo more complete. You may not even need that.
You need to make sure that the HTML template and the properties file are in the same location, because I am using the StandardMessageResolver
- see below.
I created a standalone Thymeleaf template engine class:
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.templatemode.TemplateMode;
import org.thymeleaf.templateresolver.ClassLoaderTemplateResolver;
import org.thymeleaf.context.Context;
import org.thymeleaf.extras.java8time.dialect.Java8TimeDialect;
import org.thymeleaf.messageresolver.IMessageResolver;
import org.thymeleaf.messageresolver.StandardMessageResolver;
import java.util.Map;
public class HtmlTemplateEngine {
private final TemplateEngine templateEngine;
public HtmlTemplateEngine() {
templateEngine = new org.thymeleaf.TemplateEngine();
templateEngine.addDialect(new Java8TimeDialect()); // optional extra
ClassLoaderTemplateResolver templateResolver
= new ClassLoaderTemplateResolver(Thread
.currentThread().getContextClassLoader());
templateResolver.setTemplateMode(TemplateMode.HTML);
templateResolver.setPrefix("/thymeleaf/");
templateResolver.setCacheTTLMs(3600000L); // one hour
templateResolver.setCacheable(true);
templateResolver.setCharacterEncoding("UTF-8");
templateEngine.setTemplateResolver(templateResolver);
IMessageResolver messageResolver = new StandardMessageResolver();
templateEngine.setMessageResolver(messageResolver);
}
// use this if you do not want to pass a Context (see below). It basically does
// the same as the Context-based example, by transferring Map data to a Context:
public String getTemplate(String templateName, Map<String, Object> parameters) {
Context ctx = new Context();
if (parameters != null) {
parameters.forEach((k, v) -> {
ctx.setVariable(k, v);
});
}
return this.templateEngine.process(templateName, ctx).trim();
}
public String getTemplate(String templateName, Context ctx) {
return this.templateEngine.process(templateName, ctx).trim();
}
}
Some of the entries are default values - so they could be removed without affecting anything (for example the StandardMessageResolver
will be used by default if you do not provide one).
I chose to use a ClassLoaderTemplateResolver
. There are other choices you can make.
I use the above artifacts as follows:
private void processSimpleReport() {
Map<String, Object> model = new HashMap<>();
model.put("note", "my note here");
Context ctx = new Context();
//ctx.setLocale(Locale.US); // optional for i18n
ctx.setVariables(model);
HtmlTemplateEngine engine = new HtmlTemplateEngine();
String s = engine.getTemplate("test.html", ctx);
System.out.println(s);
}
Your question only uses a message - the model
variables are just optional extras I added for this demo.
The resulting HTML is:
<!DOCTYPE html>
<html>
<p>This is a message to you.</p>
<p>my note here</p>
</html>