Skip to content

Instantly share code, notes, and snippets.

@ndemengel
Last active November 20, 2016 21:14
Show Gist options
  • Save ndemengel/5c93b93e2b1eed4038cca8598af6f75a to your computer and use it in GitHub Desktop.
Save ndemengel/5c93b93e2b1eed4038cca8598af6f75a to your computer and use it in GitHub Desktop.
JSP tag to render Handlebars templates (Java code, Spring config and TLD here: https://gist.github.com/ndemengel/2d0ce37ad326570cecfc2daccaae2267)
import lombok.Value;
@Value
public class ContextProperty {
String name;
Object value;
}
import javax.servlet.jsp.JspTagException;
public interface ContextPropertyAware {
void addContextProperty(ContextProperty property) throws JspTagException;
}
import lombok.Setter;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class ContextPropertyTag extends BodyTagSupport {
@Setter
private String name;
@Setter
private Object value;
@Override
public int doEndTag() throws JspException {
ContextPropertyAware propertyAwareTag = (ContextPropertyAware) findAncestorWithClass(this, ContextPropertyAware.class);
if (propertyAwareTag == null) {
throw new JspException("The contextProperty tag must be a descendant of a tag that supports context properties");
}
propertyAwareTag.addContextProperty(new ContextProperty(name, value));
return EVAL_PAGE;
}
@Override
public void release() {
super.release();
this.name = null;
this.value = null;
}
}
import com.github.jknack.handlebars.Handlebars;
import lombok.Setter;
import org.springframework.web.context.WebApplicationContext;
import javax.servlet.jsp.*;
import javax.servlet.jsp.tagext.TagSupport;
import java.io.IOException;
import java.util.*;
import static java.util.Collections.emptyMap;
import static java.util.stream.Collectors.toMap;
import static org.springframework.web.context.support.WebApplicationContextUtils.getWebApplicationContext;
public class RenderTag extends TagSupport implements ContextPropertyAware {
@Setter
private Object context;
@Setter
private String template;
private List<ContextProperty> contextProperties = new ArrayList<>();
@Override
public int doStartTag() throws JspException {
contextProperties = new ArrayList<>();
return EVAL_BODY_INCLUDE;
}
@Override
public int doEndTag() throws JspException {
WebApplicationContext appContext = getWebApplicationContext(pageContext.getServletContext());
Handlebars handlebars = appContext.getBean(Handlebars.class);
try {
handlebars.compile(template).apply(getOrBuildContext(), pageContext.getOut());
return EVAL_PAGE;
} catch (IOException ex) {
throw new JspException(ex.toString(), ex);
}
}
private Object getOrBuildContext() {
if (context != null) {
return context;
}
if (contextProperties == null) {
return emptyMap();
}
return contextProperties.stream().collect(toMap(ContextProperty::getName, ContextProperty::getValue));
}
@Override
public void addContextProperty(ContextProperty property) throws JspTagException {
contextProperties.add(property);
}
@Override
public void release() {
super.release();
context = null;
template = null;
contextProperties = null;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment