API / Apache FreeMarker Interview questions
How do you create a custom directive in FreeMarker using TemplateDirectiveModel?
Implementing freemarker.template.TemplateDirectiveModel lets Java code define a brand-new tag that behaves like a built-in directive such as <#if>. The interface has one method, execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body), which receives the current environment, the tag's named parameters, any loop variables it declares, and a callback to render its nested body.
public class UpperCaseDirective implements TemplateDirectiveModel { public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { StringWriter sw = new StringWriter(); body.render(sw); env.getOut().write(sw.toString().toUpperCase()); } }
The instance is exposed to templates via configuration.setSharedVariable("upper", new UpperCaseDirective()), after which it is used as <@upper>shout this</@upper>. Custom directives are the right tool when logic needs to intercept or transform a body of markup, which a plain macro cannot do as cleanly.
More Related questions...