Apache FreeMarker is a template engine: a Java library to generate text output based on templates and changing data.
—
This document covers the essential classes and methods for template loading, configuration, and processing in Apache FreeMarker.
The Configuration class is the main entry point for FreeMarker. It manages global settings, template loading, and serves as a factory for Template instances.
class Configuration extends Configurable implements Cloneable, ParserConfiguration {
// Constructors
Configuration(Version incompatibleImprovements);
// Template loading methods
Template getTemplate(String name) throws IOException;
Template getTemplate(String name, Locale locale) throws IOException;
Template getTemplate(String name, Locale locale, String encoding) throws IOException;
Template getTemplate(String name, Locale locale, String encoding, boolean parseAsFTL) throws IOException;
// Template loader configuration
void setDirectoryForTemplateLoading(File dir) throws IOException;
void setClassForTemplateLoading(Class resourceLoaderClass, String basePackagePath);
void setTemplateLoader(TemplateLoader templateLoader);
void setTemplateLookupStrategy(TemplateLookupStrategy templateLookupStrategy);
void setTemplateNameFormat(TemplateNameFormat templateNameFormat);
// Object wrapping configuration
void setObjectWrapper(ObjectWrapper objectWrapper);
ObjectWrapper getObjectWrapper();
// Encoding and locale settings
void setDefaultEncoding(String encoding);
String getDefaultEncoding();
void setLocale(Locale locale);
Locale getLocale();
void setTimeZone(TimeZone timeZone);
TimeZone getTimeZone();
// Output format configuration
void setOutputFormat(OutputFormat outputFormat);
OutputFormat getOutputFormat();
void setRegisteredCustomOutputFormats(Collection<? extends OutputFormat> registeredCustomOutputFormats);
// General configuration methods
void setSetting(String name, String value) throws TemplateException;
String getSetting(String key);
Properties getSettings() throws TemplateException;
Version getVersion();
Version getIncompatibleImprovements();
// Cache configuration
void setCacheStorage(CacheStorage cacheStorage);
CacheStorage getCacheStorage();
void clearTemplateCache();
void removeTemplateFromCache(String name);
void removeTemplateFromCache(String name, Locale locale);
void removeTemplateFromCache(String name, Locale locale, String encoding);
// Exception handling
void setTemplateExceptionHandler(TemplateExceptionHandler templateExceptionHandler);
TemplateExceptionHandler getTemplateExceptionHandler();
void setAttemptExceptionReporter(AttemptExceptionReporter attemptExceptionReporter);
AttemptExceptionReporter getAttemptExceptionReporter();
// Auto-escaping and output formats
void setAutoEscapingPolicy(int autoEscapingPolicy);
int getAutoEscapingPolicy();
void setRecognizeStandardFileExtensions(boolean recognizeStandardFileExtensions);
boolean getRecognizeStandardFileExtensions();
}// Basic file-based configuration
Configuration cfg = new Configuration(Configuration.VERSION_2_3_34);
cfg.setDirectoryForTemplateLoading(new File("/path/to/templates"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
// Classpath-based configuration
Configuration cfg = new Configuration(Configuration.VERSION_2_3_34);
cfg.setClassForTemplateLoading(MyClass.class, "/templates");
cfg.setDefaultEncoding("UTF-8");
// Custom object wrapper
Configuration cfg = new Configuration(Configuration.VERSION_2_3_34);
cfg.setObjectWrapper(new DefaultObjectWrapper(Configuration.VERSION_2_3_34));
// Auto-escaping configuration
cfg.setAutoEscapingPolicy(Configuration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY);
cfg.setOutputFormat(HTMLOutputFormat.INSTANCE);The Template class represents a parsed template ready for processing.
class Template extends Configurable {
// Constructors
Template(String name, Reader reader, Configuration cfg) throws IOException;
Template(String name, Reader reader, Configuration cfg, String encoding) throws IOException;
Template(String name, String sourceCode, Configuration cfg) throws IOException;
// Processing methods
void process(Object dataModel, Writer out) throws TemplateException, IOException;
void process(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException;
void process(Object dataModel, Writer out, ObjectWrapper wrapper, Locale locale) throws TemplateException, IOException;
// Environment creation
Environment createProcessingEnvironment(Object dataModel, Writer out) throws TemplateException, IOException;
Environment createProcessingEnvironment(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException;
// Template information
String getName();
String getEncoding();
Configuration getConfiguration();
Object getCustomLookupCondition();
Version getTemplateLanguageVersion();
String getSourceName();
// Processing control
void setCustomAttribute(Object key, Object value);
Object getCustomAttribute(Object key);
void removeCustomAttribute(Object key);
Enumeration getCustomAttributeNames();
}// Basic template processing
Template template = cfg.getTemplate("hello.ftl");
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("user", "John Doe");
Writer out = new StringWriter();
template.process(dataModel, out);
String result = out.toString();
// Processing with custom wrapper
Template template = cfg.getTemplate("advanced.ftl");
ObjectWrapper wrapper = new DefaultObjectWrapper(Configuration.VERSION_2_3_34);
template.process(dataModel, out, wrapper);
// Creating processing environment for advanced control
Environment env = template.createProcessingEnvironment(dataModel, out);
env.setGlobalVariable("currentTime", new SimpleDate(new Date(), TemplateDateModel.DATETIME));
env.process();The Environment class represents the runtime context during template processing.
class Environment extends Configurable {
// Processing control
void process() throws TemplateException, IOException;
void include(Template template) throws TemplateException, IOException;
void include(String name) throws TemplateException, IOException;
void visit(TemplateNodeModel node) throws TemplateException, IOException;
void visit(TemplateNodeModel node, TemplateSequenceModel namespaces) throws TemplateException, IOException;
// Namespace management
TemplateHashModel getCurrentNamespace() throws TemplateException;
TemplateHashModel getMainNamespace();
TemplateHashModel getDataModel();
// Variable management
void setGlobalVariable(String name, TemplateModel model) throws TemplateException;
void setVariable(String name, TemplateModel model) throws TemplateException;
void setLocalVariable(String name, TemplateModel model) throws TemplateException;
TemplateModel getGlobalVariable(String name) throws TemplateException;
TemplateModel getVariable(String name) throws TemplateException;
TemplateModel getLocalVariable(String name) throws TemplateException;
// Context information
Object getDataModel();
Writer getOut();
Template getTemplate();
TemplateNodeModel getCurrentVisitorNode() throws TemplateException;
TemplateModel getNodeProcessor(String nodeName) throws TemplateException;
// Directive and transform management
TemplateTransformModel getTransform(String key) throws TemplateException;
void visitByHiddingParent(TemplateNodeModel node) throws TemplateException, IOException;
void invokeDirective(String directiveName, Map parameters, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException;
// URL and import utilities
String toFullTemplateName(String baseName, String targetName) throws TemplateException;
TemplateModel getLastReturnValue();
Locale getLocale();
void setOut(Writer out);
// Error handling context
void outputInstructionStack(PrintWriter pw);
String getCurrentRecursionStepLocation() throws TemplateException;
}// Advanced template processing with environment control
Template template = cfg.getTemplate("complex.ftl");
Environment env = template.createProcessingEnvironment(dataModel, out);
// Set global variables accessible throughout template processing
env.setGlobalVariable("appName", new SimpleScalar("MyApplication"));
env.setGlobalVariable("buildNumber", new SimpleNumber(12345));
// Process the template
env.process();
// Access processing results
Object lastReturn = env.getLastReturnValue();The typical FreeMarker processing lifecycle follows these steps:
Configuration instanceConfiguration.getTemplate() to load and parse templatesTemplate.process() or create an Environment for advanced control// 1. Configuration setup
Configuration cfg = new Configuration(Configuration.VERSION_2_3_34);
cfg.setDirectoryForTemplateLoading(new File("templates"));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
cfg.setLogTemplateExceptions(false);
cfg.setWrapUncheckedExceptions(true);
// 2. Data model preparation
Map<String, Object> root = new HashMap<>();
root.put("user", new User("John", "Doe"));
root.put("products", getProducts());
root.put("latestProduct", getLatestProduct());
// 3. Template loading and processing
Template template = cfg.getTemplate("product-catalog.ftl");
Writer out = new FileWriter("output.html");
template.process(root, out);
out.close();// Version constants
static final Version VERSION_2_3_0 = new Version(2, 3, 0);
static final Version VERSION_2_3_34 = new Version(2, 3, 34);
// Auto-escaping policy constants
static final int DISABLE_AUTO_ESCAPING_POLICY = 20;
static final int ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY = 21;
static final int ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY = 22;
static final int FORCE_AUTO_ESCAPING_POLICY = 23;
// Template exception handler constants
static final TemplateExceptionHandler IGNORE_HANDLER;
static final TemplateExceptionHandler DEBUG_HANDLER;
static final TemplateExceptionHandler HTML_DEBUG_HANDLER;
static final TemplateExceptionHandler RETHROW_HANDLER;Install with Tessl CLI
npx tessl i tessl/maven-org-freemarker--freemarker