Skip to content

Instantly share code, notes, and snippets.

@kdonald
Created January 12, 2012 21:38
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kdonald/1603296 to your computer and use it in GitHub Desktop.
Save kdonald/1603296 to your computer and use it in GitHub Desktop.
JMustache Spring MVC Integration
build.gradle
------------
jmustacheVersion = '1.5'
dependencies {
compile 'com.samskivert:jmustache:$jmustacheVersion'
}
JMustacheViewResolver.java
--------------------------
package org.springframework.servlet.mvc.view.jmustache;
import java.io.InputStreamReader;
import java.io.Reader;
import java.io.Writer;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.core.io.ResourceLoader;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.view.AbstractTemplateView;
import org.springframework.web.servlet.view.AbstractTemplateViewResolver;
import org.springframework.web.servlet.view.AbstractUrlBasedView;
import com.samskivert.mustache.Mustache;
import com.samskivert.mustache.Mustache.Compiler;
import com.samskivert.mustache.Mustache.TemplateLoader;
import com.samskivert.mustache.Template;
public class JMustacheViewResolver extends AbstractTemplateViewResolver implements ViewResolver {
private TemplateLoader templateLoader;
private Compiler compiler;
public JMustacheViewResolver(ResourceLoader resourceLoader) {
setViewClass(JMustacheView.class);
setExposeSpringMacroHelpers(false);
setSuffix(".html");
initJMustache(resourceLoader);
}
@Override
protected Class<?> requiredViewClass() {
return JMustacheView.class;
}
@Override
protected AbstractUrlBasedView buildView(String viewName) throws Exception {
JMustacheView view = (JMustacheView) super.buildView(viewName);
Template template = compiler.compile(templateLoader.getTemplate(view.getUrl()));
view.setTemplate(template);
return view;
}
private void initJMustache(ResourceLoader resourceLoader) {
templateLoader = new ResourceTemplateLoader(resourceLoader);
compiler = Mustache.compiler().nullValue("").withLoader(templateLoader);
}
private static class ResourceTemplateLoader implements TemplateLoader {
private static final String DEFAULT_ENCODING = "UTF-8";
private final ResourceLoader resourceLoader;
private String encoding = DEFAULT_ENCODING;
public ResourceTemplateLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
@Override
public Reader getTemplate(String name) throws Exception {
return new InputStreamReader(resourceLoader.getResource(name).getInputStream(), encoding);
}
}
private static class JMustacheView extends AbstractTemplateView {
private Template template;
public void setTemplate(Template template) {
this.template = template;
}
@Override
protected void renderMergedTemplateModel(Map<String, Object> model, HttpServletRequest request,
HttpServletResponse response) throws Exception {
response.setContentType(getContentType());
Writer writer = response.getWriter();
try {
template.execute(model, writer);
} finally {
writer.flush();
}
}
}
}
example template - index.html
-----------------------------
<html>
<head>
<title>Index</title>
</head>
<body>
<p>{{ message }}</p>
</body>
</html>
example controller - index controller
-------------------------------------
@Controller
public class IndexController {
@RequestMapping(value="/", method=RequestMethod.GET)
public String index(Model model) {
model.addAttribute("message", "Hello world!");
return "index";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment