How to Generate Dynamic Content using Mustache Templates?
Last Updated :
28 Apr, 2025
Mustache is a logicless template engine and it is helpful for creating dynamic content like HTML and configuration files. Logicless means it does not have a structured flow with if else/for loops/while loops etc., It just contains tag names surrounded by { { } } and hence they are called Mustache templates(that resembles a mustache). A model object is required which contains the data to be filled in the template. Let us see the functionality via a maven project. For that let us see the Maven dependency first.
Maven dependency:
Multiple languages can use Compilation and execution of the templates. Languages can be both on the client side and server side. Let us use a Java library that can be added as a Maven dependency.
For Java 8:
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.4</version>
</dependency>
For Java 6/7:
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.8.18</version>
</dependency>
Example Project
Project Structure:
As it is a maven project. let us see pom.xml
pom.xml
XML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<artifactId>mustache</artifactId>
<name>mustache</name>
<packaging>jar</packaging>
<parent>
<groupId>com.gfg</groupId>
<artifactId>parent-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<relativePath>../parent-boot-2</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>${mustache.compiler.api.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mustache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>${webjars.bootstrap.version}</version>
</dependency>
<dependency>
<groupId>org.fluttercode.datafactory</groupId>
<artifactId>datafactory</artifactId>
<version>${datafactory.version}</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<properties>
<mustache.compiler.api.version>0.9.10</mustache.compiler.api.version>
<datafactory.version>0.8</datafactory.version>
<webjars.bootstrap.version>3.3.7</webjars.bootstrap.version>
</properties>
</project>
Let us see how to create a Simple template
<h2>{{title}}</h2>
<small>Created on {{createdOn}}</small>
<p>{{text}}</p>
This template will be helpful to display the details that are present in TodoItems. ({{}}) is mainly helpful for getting
- Methods and Properties of a Java class
- Keys of a Map object
For compiling the Mustache Template, we need to use MustacheFactory. Here in our program, it searches for the template that is present in classpath, and here it is available at src/main/resources. For compiling the template
MustacheFactory mustacheFactory = new DefaultMustacheFactory();
Mustache mustache = mustacheFactory.compile("todoitems.mustache");
Example of a template file
<div class="starter-template">
{{#articles}}
<h1>{{title}}</h1>
<h3>{{publishDate}}</h3>
<h3>{{author}}</h3>
<p>{{body}}</p>
{{/articles}}
</div>
Let us see a model file that produces the data
TodoItems.java
Java
import java.time.Duration;
import java.util.Date;
import java.util.function.Function;
public class TodoItems {
public TodoItems() {
}
public TodoItems(String title, String text) {
this.itemTitle = title;
this.itemText = text;
createdDate = new Date();
}
private String itemTitle;
private String itemText;
private boolean done = false;
private Date createdDate;
private Date completedDate;
public void markAsDone() {
done = true;
completedDate = new Date();
}
public String getTitle() {
return itemTitle;
}
public void setTitle(String title) {
this.itemTitle = title;
}
public String getText() {
return itemText;
}
public void setText(String text) {
this.itemText = text;
}
public boolean getDone() {
return done;
}
public Date getCreatedOn() {
return createdDate;
}
public Date getCompletedOn() {
return completedDate;
}
public void setDone(boolean done) {
this.done = done;
}
public void setCompletedOn(Date completedOn) {
this.completedDate = completedOn;
}
public long doneSince() {
return done ? Duration
.between(createdDate.toInstant(), completedDate.toInstant())
.toMinutes() : 0;
}
public Function<Object, Object> handleDone() {
return (obj) -> done ? String.format("<small>Done %s minutes ago<small>", obj) : "";
}
}
The compiled template which produces HTML is as follows
TodoItems todoItems = new TodoItems("Todo 1", "Description");
StringWriter writer = new StringWriter();
m.execute(writer, todoItems).flush();
String html = writer.toString();
Not only sequential data, but the list of data also, but it can also be supported via
{{#todo}}
<!-- Other code -->
{{/todo}}
The important thing that needs to be noted is the # and/or which represents the basis for rendering the section. As a spring project, the data rendering also happening. Hence let us see the key files to execute it
MustacheUtil.java
Java
import com.github.mustachejava.DefaultMustacheFactory;
import com.github.mustachejava.MustacheFactory;
public class MustacheUtil {
private static final MustacheFactory mf = new DefaultMustacheFactory();
public static MustacheFactory getMustacheFactory(){
return mf;
}
}
SpringMustacheApplication.java
Java
import com.samskivert.mustache.DefaultCollector;
import com.samskivert.mustache.Mustache;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
@SpringBootApplication
@ComponentScan(basePackages = {"com.gfg"})
public class SpringMustacheApplication {
public static void main(String[] args) {
SpringApplication.run(SpringMustacheApplication.class, args);
}
@Bean
public Mustache.Compiler mustacheCompiler(Mustache.TemplateLoader templateLoader) {
return Mustache.compiler()
// Here if the value is not provided
// then defaultValue will be taken
.defaultValue("Some Author")
.withLoader(templateLoader)
.withCollector(new DefaultCollector());
}
}
GeekArticleController.java
Java
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.fluttercode.datafactory.impl.DataFactory;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
import com.gfg.springmustache.model.GeekArticle;
@Controller
public class GeekArticleController {
@GetMapping("/article")
public ModelAndView displayArticle(Map<String, Object> model) {
List<GeekArticle> geekArticles = IntStream.range(0, 10)
.mapToObj(i -> generateArticle("Article Title " + i))
.collect(Collectors.toList());
model.put("articles", geekArticles);
return new ModelAndView("index", model);
}
private GeekArticle generateArticle(String title) {
GeekArticle geekArticle = new GeekArticle();
DataFactory factory = new DataFactory();
geekArticle.setTitle(title);
geekArticle.setBody(
"A data structure is not only used for organizing the data. It is also used for processing, retrieving, and storing data. There are different basic and advanced types of data structures that are used in almost every program or software system that has been developed. So we must have good knowledge about data structures.");
geekArticle.setPublishDate(factory.getBirthDate().toString());
//article.setAuthor(factory.getName());
return geekArticle;
}
}
GeekArticle.java
Java
public class GeekArticle {
private String geekTitle;
private String geekBody;
private String geekAuthorName;
private String publishDate;
public String getTitle() {
return geekTitle;
}
public void setTitle(String title) {
this.geekTitle = title;
}
public String getBody() {
return geekBody;
}
public void setBody(String body) {
this.geekBody = body;
}
public String getAuthor() {
return geekAuthorName;
}
public void setAuthor(String author) {
this.geekAuthorName = author;
}
public String getPublishDate() {
return publishDate;
}
public void setPublishDate(String publishDate) {
this.publishDate = publishDate;
}
}
Let us see the resources folder html key files
geekarticle.html
HTML
<div class="starter-template">
<!-- Using the list pattern Begin -->
{{#articles}}
<h1>{{title}}</h1>
<h3>{{publishDate}}</h3>
<h3>{{author}}</h3>
<p>{{body}}</p>
<!-- Using the list pattern End -->
{{/articles}}
</div>
index.html
HTML
{{>layout/header}}
<body>
<div class="container">{{>layout/geekarticle}}</div>
<script type="text/javascript"
src="webjars/bootstrap/3.3.7/js/bootstrap.min.js"></script>
</body>
{{>layout/footer}}
todo.mustache
<h2>{{title}}</h2>
<small>Created on {{createdOn}}</small>
<p>{{text}}</p>
Let us run the application as a spring boot project. The console output is shown here
On execution of the controller, we can see the below output
For producing inverted sections, we need to follow the pattern below
{{#todos}}
<h2>{{title}}</h2>
{{/todos}}
{{^todos}} // start with a caret (^) and end with a slash (/)
<p>No todos!</p>
{{/todos}}
Conclusion
In this article, we saw creating of simple or inverted mustache templates and then java API is used to compile and execute the mustache templates by providing relevant data. It is a logicless template and is supported by many languages like Java, Python, Ruby, Android, Kotlin, etc.
Similar Reads
How to Create Dynamic Web Pages using Apache Velocity? Apache Velocity is an open-source java-based templating engine that can play as an alternative to JSP (Jakarta server pages). It is helpful to generate XML files, SQL, etc., In this article, let us see the creation of dynamic web pages. Working way of Velocity: Velocity engine initializationReading
6 min read
Random Quote Generator Using HTML, CSS and JavaScript A Random Quote Generator is capable of pulling quotes randomly from an API, a database, or simply from an array. We will be designing a Random Quote Generator from scratch using HTML, CSS, JavaScript, and type.fit API. The webpage displays a random quote from a collection and upon the click of a but
8 min read
How to Add Testimonials using HTML? Testimonials are Written recommendations from users and are often seen in a separate section of a web page. In this article, we will learn how to add responsive testimonials to our web page. Generally, a testimonial contains the userâs name, picture, his/her identity(optional), and most importantly
5 min read
Placeholders in jinja2 Template - Python Web pages use HTML for the things that users see or interact with. But how do we show things from an external source or a controlling programming language like Python? To achieve this templating engine like Jinja2 is used. Jinja2 is a templating engine in which placeholders in the template allow wri
5 min read
What is V8 Templates ? As a developer, we need to use various features and tools to enhance the quality of our projects and our work and one such feature in Node.js is the V8 template. Let's take a look at these. Introduction to V8 Templates: V8 Templates in Node.js are a feature that allows developers to embed expression
8 min read