package org.jbake.template;
import groovy.lang.GString;
import groovy.lang.Writable;
import groovy.text.Template;
import groovy.text.markup.MarkupTemplateEngine;
import groovy.text.markup.TemplateConfiguration;
import org.apache.commons.configuration.CompositeConfiguration;
import org.jbake.app.ContentStore;
import java.io.File;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;
/**
* Renders documents using the GroovyMarkupTemplateEngine.
*
* The file extension to activate this Engine is .tpl
*
* @see <a href="http://groovy-lang.org/templating.html#_the_markuptemplateengine">Groovy MarkupTemplateEngine Documentation</a>
*/
public class GroovyMarkupTemplateEngine extends AbstractTemplateEngine {
private TemplateConfiguration templateConfiguration;
private MarkupTemplateEngine templateEngine;
public GroovyMarkupTemplateEngine(final CompositeConfiguration config, final ContentStore db, final File destination, final File templatesPath) {
super(config, db, destination, templatesPath);
setupTemplateConfiguration();
initializeTemplateEngine();
}
private void setupTemplateConfiguration() {
templateConfiguration = new TemplateConfiguration();
templateConfiguration.setUseDoubleQuotes(true);
templateConfiguration.setAutoIndent(true);
templateConfiguration.setAutoNewLine(true);
templateConfiguration.setAutoEscape(true);
}
private void initializeTemplateEngine() {
templateEngine = new MarkupTemplateEngine(MarkupTemplateEngine.class.getClassLoader(),templatesPath,templateConfiguration);
}
@Override
public void renderDocument(final Map<String, Object> model, final String templateName, final Writer writer) throws RenderingException {
try {
Template template = templateEngine.createTemplateByPath(templateName);
Map<String, Object> wrappedModel = wrap(model);
Writable writable = template.make(wrappedModel);
writable.writeTo(writer);
} catch (Exception e) {
throw new RenderingException(e);
}
}
private Map<String, Object> wrap(final Map<String, Object> model) {
return new HashMap<String, Object>(model) {
@Override
public Object get(final Object property) {
if (property instanceof String || property instanceof GString) {
String key = property.toString();
try {
put(key, extractors.extractAndTransform(db, key, model, new TemplateEngineAdapter.NoopAdapter()));
} catch (NoModelExtractorException e) {
// should never happen, as we iterate over existing extractors
}
}
return super.get(property);
}
};
}
}