SpringMVC Mustache allows you to render your mustache templates in your application using your favorite implementation:
For a complete documentation about Mustache Templating, feel free to check the full documentation available here: https://mustache.github.io/
Rendering your mustache templates can now be done in two steps:
- Add required dependencies
- Add
@EnableMustacheannotation to your spring configuration
Required dependencies
Java >= 8
If you are using java < 8, please use version 2.0.0:
<dependency>
<groupId>com.github.mjeanroy</groupId>
<artifactId>springmvc-mustache</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Add one of these dependencies. -->
<!-- This is the mustache implementation to use -->
<!-- You can add one of the following: -->
<dependency>
<groupId>com.samskivert</groupId>
<artifactId>jmustache</artifactId>
<version>1.15</version>
</dependency>
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>4.2.0</version>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.9.6</version>
</dependency>
Java <= 7
If you are using java <= 7, please use version 1.0.0:
<dependency>
<groupId>com.github.mjeanroy</groupId>
<artifactId>springmvc-mustache</artifactId>
<version>1.0.0</version>
</dependency>
<!-- Add one of these dependencies. -->
<!-- This is the mustache implementation to use -->
<!-- You can add one of the following: -->
<dependency>
<groupId>com.samskivert</groupId>
<artifactId>jmustache</artifactId>
<version>1.13</version>
</dependency>
<dependency>
<groupId>com.github.jknack</groupId>
<artifactId>handlebars</artifactId>
<version>4.0.6</version>
</dependency>
<dependency>
<groupId>com.github.spullara.mustache.java</groupId>
<artifactId>compiler</artifactId>
<version>0.8.17</version>
</dependency>
Starting with version 0.10.0, it is recommended to only add springmvc-mustache-[impl] dependency, it add automatically the compatible
version of your favorite implementation.
For example:
<!-- Add one of these dependencies. -->
<!-- This is the mustache implementation to use -->
<!-- You can add one of the following: -->
<!-- Use version 1.0.0 if you need java <= 7 compatibility -->
<dependency>
<groupId>com.github.mjeanroy</groupId>
<artifactId>springmvc-mustache-jmustache</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.github.mjeanroy</groupId>
<artifactId>springmvc-mustache-handlebars</artifactId>
<version>2.0.0</version>
</dependency>
<dependency>
<groupId>com.github.mjeanroy</groupId>
<artifactId>springmvc-mustache-mustachejava</artifactId>
<version>2.0.0</version>
</dependency>
Configuration
Now, you can add @EnableMustache to your spring configuration:
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import com.github.mjeanroy.springmvc.view.mustache.configuration.EnableMustache;
import com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheProvider;
@Configuration
@EnableWebMvc
@EnableMustache
@ComponentScan("com.myApp")
public class SpringConfiguration {
}
Note that if you are using SpringBoot, automatic configuration will be registered, you have nothing to do!
By default, following configuration will be used:
- Prefix:
/templates. This is the prefix used by spring view resolver to resolve view url. - Suffix:
.template.htmlThis is the suffix used by spring view resolver to resolve view url. - Cache:
trueBy default, templates are automatically cached. - View Names:
*By default, all views are mapped using spring mustache view resolver.
If you want to override these settings, add a file named mustache.properties to your application:
##
# Override default mustache configuration.
##
mustache.prefix = /mustache
mustache.suffix = .mustache
mustache.cache = false
mustache.viewNames = *
You can configure following properties:
| Property | Type | Default | Description |
|---|---|---|---|
mustache.prefix |
String |
/templates/ |
View prefix. |
mustache.suffix |
String |
.template.html |
View suffix. |
mustache.cache |
Boolean |
true |
View cache. |
mustache.viewNames |
String |
* |
View name matcher. |
mustache.defaultLayout |
String |
The default template to used with the default layout. |
Layout & Partials
SpringMVC also supports layout: define one layout and apply it accross your views.
For example, suppose this layout:
<html>
<head>
<title>My Awesome Application</title>
</head>
<body>
<div class="header">
{{> header}}
</div>
<div class="content">
{{> content}}
</div>
<div class="footer">
{{> footer}}
</div>
</body>
</html>
Here, we define three partials:
headerandfooter: it will be automatically loaded during rendering.contentwhich is a special key used to render the “current” view (the view name set in your spring controller).
And now, this is how I will render the home page:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FooController {
@GetMapping("/")
public ModelAndView fooView() {
// Just render foo template, and view resolver will automatically replace content partials
// by foo content
ModelAndView view = new ModelAndView("home");
view.addObject("name", "John Doe");
return view;
}
}
If you want to have different layouts for your views, just define some mappings that can be used to map view to layout templates:
# Define some layout mappings
# If mapping is define for a view, it will be used, otherwise default layout will be used
# Format is: [viewName]:[layoutName]
mustache.layoutMappings = admin1:secure ; admin2:secure
# Use default layout for other views
mustache.defaultLayout = index
And here is how I can render admin1 view (using the secure layout template):
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FooController {
@GetMapping("/")
public ModelAndView admin1View() {
// Just render foo template, and view resolver will automatically used "secure" template
return new ModelAndView("admin1");
}
}
Rendering
Now, you can easily render your templates:
Suppose you have this templates (say: /templates/index.template.html):
Hello, my name is {{name}}
You can render your template with Spring MVC:
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class FooController {
@GetMapping("/")
public ModelAndView fooView() {
ModelAndView view = new ModelAndView("index");
view.addObject("name", "John Doe");
return view;
}
}
SpringBoot
Finally, here is an exemple using Spring Boot:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.servlet.ModelAndView;
@EnableAutoConfiguration(exclude = MustacheAutoConfiguration.class)
@Controller
public class Application {
// Render a simple template
@GetMapping("/")
public ModelAndView fooView() {
ModelAndView modelAndView = new ModelAndView("foo");
modelAndView.addObject("name", "foo");
return modelAndView;
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
Note that since Spring-Boot provide autoconfiguration for JMustache, you will need to excluce this one explicitly to avoid conflict (but this is not needed you are using Handlebars or MustacheJava implementation).
XML Configuration
If you prefer XML configuration, you may want to use one of these (depends on the underlying implementation) :
JMustache:
<!-- Create mustache beans -->
<bean id="jmustache" class="com.github.mjeanroy.springmvc.view.mustache.configuration.jmustache.JMustacheCompilerFactoryBean" />
<bean id="mustacheTemplateLoader" class="com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheTemplateLoaderFactoryBean" />
<bean id="mustacheCompiler" class="com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheCompilerFactoryBean" />
<!-- Create view resolver -->
<bean class="com.github.mjeanroy.springmvc.view.mustache.MustacheViewResolver">
<constructor-arg ref="mustacheCompiler" />
<property name="order" value="1" />
<property name="defaultLayout" value="layout" />
<property name="prefix" value="templates/" />
<property name="suffix" value=".template.html" />
</bean>
Handlebars:
<!-- Create mustache beans -->
<bean id="handlebars" class="com.github.mjeanroy.springmvc.view.mustache.configuration.handlebars.HandlebarsFactoryBean" />
<bean id="mustacheTemplateLoader" class="com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheTemplateLoaderFactoryBean" />
<bean id="mustacheCompiler" class="com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheCompilerFactoryBean" />
<!-- Create view resolver -->
<bean class="com.github.mjeanroy.springmvc.view.mustache.MustacheViewResolver">
<constructor-arg ref="mustacheCompiler" />
<property name="order" value="1" />
<property name="defaultLayout" value="layout" />
<property name="prefix" value="templates/" />
<property name="suffix" value=".template.html" />
</bean>
MustacheJava:
<!-- Create mustache beans -->
<bean id="mustacheTemplateLoader" class="com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheTemplateLoaderFactoryBean" />
<bean id="mustacheFactory" class="com.github.mjeanroy.springmvc.view.mustache.mustachejava.SpringMustacheFactory">
<constructor-arg ref="mustacheTemplateLoader"/>
</bean>
<bean id="mustacheResolver" class="com.github.mjeanroy.springmvc.view.mustache.mustachejava.SpringMustacheResolver">
<constructor-arg ref="mustacheTemplateLoader"/>
</bean>
<bean id="mustacheCompiler" class="com.github.mjeanroy.springmvc.view.mustache.configuration.MustacheCompilerFactoryBean" />
<!-- Create view resolver -->
<bean class="com.github.mjeanroy.springmvc.view.mustache.MustacheViewResolver">
<constructor-arg ref="mustacheCompiler" />
<property name="order" value="1" />
<property name="defaultLayout" value="layout" />
<property name="prefix" value="templates/" />
<property name="suffix" value=".template.html" />
</bean>