Apache FreeMarker is a template engine: a Java library to generate text output based on templates and changing data.
npx @tessl/cli install tessl/maven-org-freemarker--freemarker@2.3.0Apache FreeMarker is a template engine: a Java library to generate text output (HTML web pages, e-mails, configuration files, source code, etc.) based on templates and changing data. FreeMarker provides a powerful templating language with features like variable substitution, conditional logic, loops, macros, and built-in functions for processing collections, strings, numbers, and dates.
Package Name: org.freemarker:freemarker
Package Type: Maven (Java)
Language: Java
Installation:
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.34</version>
</dependency>Gradle:
implementation 'org.freemarker:freemarker:2.3.34'import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.Version;import freemarker.template.*;
import java.io.*;
import java.util.*;
// Create and configure FreeMarker
Configuration cfg = new Configuration(Configuration.VERSION_2_3_34);
cfg.setDirectoryForTemplateLoading(new File("templates"));
cfg.setDefaultEncoding("UTF-8");
// Create data model
Map<String, Object> dataModel = new HashMap<>();
dataModel.put("user", "John Doe");
dataModel.put("items", Arrays.asList("Apple", "Banana", "Cherry"));
// Get template and process
Template template = cfg.getTemplate("hello.ftl");
Writer out = new StringWriter();
template.process(dataModel, out);
System.out.println(out.toString());FreeMarker follows a clean separation between:
Essential classes and methods for template loading, configuration, and processing.
// Main configuration class
class Configuration {
Configuration(Version incompatibleImprovements);
Template getTemplate(String name) throws IOException;
Template getTemplate(String name, Locale locale) throws IOException;
Template getTemplate(String name, Locale locale, String encoding) throws IOException;
void setDirectoryForTemplateLoading(File dir) throws IOException;
void setClassForTemplateLoading(Class resourceLoaderClass, String basePackagePath);
void setTemplateLoader(TemplateLoader templateLoader);
void setObjectWrapper(ObjectWrapper objectWrapper);
void setDefaultEncoding(String encoding);
void setLocale(Locale locale);
void setTimeZone(TimeZone timeZone);
void setOutputFormat(OutputFormat outputFormat);
void setSetting(String name, String value) throws TemplateException;
Version getVersion();
}
// Template representation
class Template {
Template(String name, Reader reader, Configuration cfg) throws IOException;
void process(Object dataModel, Writer out) throws TemplateException, IOException;
void process(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException;
Environment createProcessingEnvironment(Object dataModel, Writer out) throws TemplateException, IOException;
String getName();
String getEncoding();
Configuration getConfiguration();
}
// Processing environment
class Environment {
void process() throws TemplateException, IOException;
void include(Template template) throws TemplateException, IOException;
TemplateHashModel getCurrentNamespace() throws TemplateException;
TemplateHashModel getMainNamespace();
void setGlobalVariable(String name, TemplateModel model) throws TemplateException;
TemplateModel getGlobalVariable(String name) throws TemplateException;
Object getDataModel();
Writer getOut();
}Interfaces for representing different data types in templates, enabling seamless integration between Java objects and FreeMarker templates.
// Base interface for all template values
interface TemplateModel {
TemplateModel NOTHING = GeneralPurposeNothing.INSTANCE;
}
// String values
interface TemplateScalarModel extends TemplateModel {
String getAsString() throws TemplateModelException;
}
// Numeric values
interface TemplateNumberModel extends TemplateModel {
Number getAsNumber() throws TemplateModelException;
}
// Boolean values
interface TemplateBooleanModel extends TemplateModel {
boolean getAsBoolean() throws TemplateModelException;
TemplateBooleanModel TRUE = TrueBooleanModel.INSTANCE;
TemplateBooleanModel FALSE = FalseBooleanModel.INSTANCE;
}
// Date/time values
interface TemplateDateModel extends TemplateModel {
Date getAsDate() throws TemplateModelException;
int getDateType();
int DATE = 1;
int TIME = 2;
int DATETIME = 3;
int UNKNOWN = 0;
}
// Sequence/list access
interface TemplateSequenceModel extends TemplateModel {
TemplateModel get(int index) throws TemplateModelException;
int size() throws TemplateModelException;
}
// Hash/map access
interface TemplateHashModel extends TemplateModel {
TemplateModel get(String key) throws TemplateModelException;
boolean isEmpty() throws TemplateModelException;
}Convert Java objects to TemplateModel objects for use in templates.
// Core object wrapper interface
interface ObjectWrapper {
TemplateModel wrap(Object obj) throws TemplateModelException;
}
// Default object wrapper with comprehensive Java object support
class DefaultObjectWrapper extends BeansWrapper {
DefaultObjectWrapper(Version incompatibleImprovements);
static DefaultObjectWrapper getDefaultInstance();
}
// Builder for creating configured DefaultObjectWrapper instances
class DefaultObjectWrapperBuilder {
DefaultObjectWrapperBuilder(Version incompatibleImprovements);
DefaultObjectWrapper build();
DefaultObjectWrapperBuilder setExposeFields(boolean exposeFields);
DefaultObjectWrapperBuilder setForceLegacyNonListCollections(boolean force);
}
// Bean wrapper for Java beans with property and method access
class BeansWrapper implements RichObjectWrapper {
BeansWrapper(Version incompatibleImprovements);
TemplateHashModel getStaticModels();
TemplateHashModel getEnumModels();
void setExposeFields(boolean exposeFields);
void setMethodAppearanceFineTuner(MethodAppearanceFineTuner tuner);
TemplateModel unwrap(TemplateModel model) throws TemplateModelException;
}Control how templates are loaded, cached, and resolved from various sources.
// Core template loading interface
interface TemplateLoader {
Object findTemplateSource(String name) throws IOException;
long getLastModified(Object templateSource);
Reader getReader(Object templateSource, String encoding) throws IOException;
void closeTemplateSource(Object templateSource) throws IOException;
}
// File system template loading
class FileTemplateLoader implements TemplateLoader {
FileTemplateLoader(File baseDir) throws IOException;
FileTemplateLoader(File baseDir, boolean disableCanonicalization) throws IOException;
}
// Classpath template loading
class ClassTemplateLoader extends URLTemplateLoader {
ClassTemplateLoader(Class resourceLoaderClass, String basePackagePath);
}
// In-memory string template loading
class StringTemplateLoader implements TemplateLoader {
StringTemplateLoader();
void putTemplate(String name, String templateSource);
void removeTemplate(String name);
}
// Cache storage interface
interface CacheStorage {
Object get(Object key);
void put(Object key, Object value);
void remove(Object key);
void clear();
}Extend FreeMarker with custom functionality and integrate with external systems.
// Custom directive interface
interface TemplateDirectiveModel extends TemplateModel {
void execute(Environment env, Map params, TemplateModel[] loopVars,
TemplateDirectiveBody body) throws TemplateException, IOException;
}
// Custom method interface
interface TemplateMethodModelEx extends TemplateMethodModel {
Object exec(List arguments) throws TemplateModelException;
}
// Text transformation interface
interface TemplateTransformModel extends TemplateModel {
Writer getWriter(Writer out, Map args) throws TemplateModelException, IOException;
}
// XML/DOM node model
class NodeModel implements TemplateNodeModel, TemplateHashModel, TemplateSequenceModel {
static NodeModel wrap(Node node);
static NodeModel parse(InputSource is) throws SAXException, IOException, ParserConfigurationException;
Node getNode();
String getNodeName() throws TemplateModelException;
String getNodeType() throws TemplateModelException;
}Control output formatting and automatic escaping for different content types.
// Base output format
abstract class OutputFormat {
abstract String getName();
abstract String getMimeType();
abstract boolean isOutputFormatMixingAllowed(OutputFormat otherOutputFormat);
}
// HTML output format with automatic escaping
class HTMLOutputFormat extends CommonMarkupOutputFormat {
static final HTMLOutputFormat INSTANCE;
}
// XML output format
class XMLOutputFormat extends CommonMarkupOutputFormat {
static final XMLOutputFormat INSTANCE;
}
// Plain text (no escaping)
class PlainTextOutputFormat extends OutputFormat {
static final PlainTextOutputFormat INSTANCE;
}Handle template processing errors and exceptions.
// Base template exception
class TemplateException extends Exception {
TemplateException(String description, Environment env);
TemplateException(String description, Environment env, Throwable cause);
String getFTLInstructionStack();
int getLineNumber();
int getColumnNumber();
String getTemplateName();
}
// Template model exceptions
class TemplateModelException extends TemplateException {
TemplateModelException(String description);
TemplateModelException(String description, Throwable cause);
}
// Exception handler interface
interface TemplateExceptionHandler {
void handleTemplateException(TemplateException te, Environment env, Writer out)
throws TemplateException;
TemplateExceptionHandler IGNORE_HANDLER = IgnoreTemplateExceptionHandler.INSTANCE;
TemplateExceptionHandler DEBUG_HANDLER = DebugTemplateExceptionHandler.INSTANCE;
TemplateExceptionHandler HTML_DEBUG_HANDLER = HtmlDebugTemplateExceptionHandler.INSTANCE;
TemplateExceptionHandler RETHROW_HANDLER = RethrowTemplateExceptionHandler.INSTANCE;
}// Version information
class Version implements Serializable {
Version(String version) throws NumberFormatException;
Version(int major, int minor, int micro);
int getMajor();
int getMinor();
int getMicro();
String toString();
static final Version VERSION_2_3_0 = new Version(2, 3, 0);
static final Version VERSION_2_3_19 = new Version(2, 3, 19);
static final Version VERSION_2_3_20 = new Version(2, 3, 20);
static final Version VERSION_2_3_21 = new Version(2, 3, 21);
static final Version VERSION_2_3_22 = new Version(2, 3, 22);
static final Version VERSION_2_3_23 = new Version(2, 3, 23);
static final Version VERSION_2_3_24 = new Version(2, 3, 24);
static final Version VERSION_2_3_25 = new Version(2, 3, 25);
static final Version VERSION_2_3_26 = new Version(2, 3, 26);
static final Version VERSION_2_3_27 = new Version(2, 3, 27);
static final Version VERSION_2_3_28 = new Version(2, 3, 28);
static final Version VERSION_2_3_29 = new Version(2, 3, 29);
static final Version VERSION_2_3_30 = new Version(2, 3, 30);
static final Version VERSION_2_3_31 = new Version(2, 3, 31);
static final Version VERSION_2_3_32 = new Version(2, 3, 32);
static final Version VERSION_2_3_33 = new Version(2, 3, 33);
static final Version VERSION_2_3_34 = new Version(2, 3, 34);
static final Version DEFAULT_INCOMPATIBLE_IMPROVEMENTS = Configuration.VERSION_2_3_0;
}
// Template directive body for custom directives
interface TemplateDirectiveBody {
void render(Writer out) throws TemplateException, IOException;
}
// Iterator for template models
interface TemplateModelIterator {
TemplateModel next() throws TemplateModelException;
boolean hasNext() throws TemplateModelException;
}
// Key-value pair for hash iteration
interface KeyValuePair {
TemplateModel getKey() throws TemplateModelException;
TemplateModel getValue() throws TemplateModelException;
}
// Configuration interface for configurable objects
abstract class Configurable {
void setSetting(String name, String value) throws TemplateException;
String getSetting(String key);
void setLocale(Locale locale);
Locale getLocale();
void setTimeZone(TimeZone timeZone);
TimeZone getTimeZone();
void setOutputFormat(OutputFormat outputFormat);
OutputFormat getOutputFormat();
}