public class Template extends Configurable
Stores an already parsed template, ready to be processed (rendered) for unlimited times, possibly from multiple threads.
Typically, you will use Configuration.getTemplate(String)
to create/get Template
objects, so
you don't construct them directly. But you can also construct a template from a Reader
or a String
that contains the template source code. But then it's
important to know that while the resulting Template
is efficient for later processing, creating a new
Template
itself is relatively expensive. So try to re-use Template
objects if possible.
Configuration.getTemplate(String)
does that (caching Template
-s) for you, but the constructor of
course doesn't, so it's up to you to solve then.
Objects of this class meant to be handled as immutable and thus thread-safe. However, it has some setter methods for changing FreeMarker settings. Those must not be used while the template is being processed, or if the template object is already accessible from multiple threads.
Modifier and Type | Class and Description |
---|---|
static class |
Template.WrongEncodingException
Thrown by the
Template constructors that specify a non-null encoding whoch doesn't match the
encoding specified in the #ftl header of the template. |
Configurable.SettingValueAssignmentException, Configurable.UnknownSettingException
Modifier and Type | Field and Description |
---|---|
static String |
DEFAULT_NAMESPACE_PREFIX |
static String |
NO_NS_PREFIX |
API_BUILTIN_ENABLED_KEY, ARITHMETIC_ENGINE_KEY, AUTO_FLUSH_KEY, BOOLEAN_FORMAT_KEY, CLASSIC_COMPATIBLE_KEY, DATE_FORMAT_KEY, DATETIME_FORMAT_KEY, LOCALE_KEY, LOG_TEMPLATE_EXCEPTIONS_KEY, NEW_BUILTIN_CLASS_RESOLVER_KEY, NUMBER_FORMAT_KEY, OBJECT_WRAPPER_KEY, OUTPUT_ENCODING_KEY, SHOW_ERROR_TIPS_KEY, SQL_DATE_AND_TIME_TIME_ZONE_KEY, STRICT_BEAN_MODELS, STRICT_BEAN_MODELS_KEY, TEMPLATE_EXCEPTION_HANDLER_KEY, TIME_FORMAT_KEY, TIME_ZONE_KEY, URL_ESCAPING_CHARSET_KEY
Constructor and Description |
---|
Template(String name,
Reader reader)
Deprecated.
This constructor uses the "default"
Configuration
instance, which can easily lead to erroneous, unpredictable behavior.
See more here... . |
Template(String name,
Reader reader,
Configuration cfg)
|
Template(String name,
Reader reader,
Configuration cfg,
String encoding)
Deprecated.
In most applications, use
Template(String, Reader, Configuration) instead, which doesn't
specify the encoding. |
Template(String name,
String sourceCode,
Configuration cfg)
Convenience constructor for
Template(name, new StringReader(reader), cfg) . |
Template(String name,
String sourceName,
Reader reader,
Configuration cfg)
Constructs a template from a character stream.
|
Template(String name,
String sourceName,
Reader reader,
Configuration cfg,
String encoding)
Deprecated.
In most applications, use
Template(String, String, Reader, Configuration) instead, which
doesn't specify the encoding. |
Modifier and Type | Method and Description |
---|---|
void |
addImport(freemarker.core.LibraryLoad ll)
Deprecated.
Should only be used internally, and might will be removed later.
|
void |
addMacro(freemarker.core.Macro macro)
Deprecated.
Should only be used internally, and might will be removed later.
|
void |
addPrefixNSMapping(String prefix,
String nsURI)
Deprecated.
Should only be used internally, and might will be removed later.
|
TreePath |
containingElements(int column,
int line)
Deprecated.
Should only be used internally, and might will be removed later.
|
Environment |
createProcessingEnvironment(Object dataModel,
Writer out)
|
Environment |
createProcessingEnvironment(Object dataModel,
Writer out,
ObjectWrapper wrapper)
Creates a
Environment object, using this template, the data-model provided as
parameter. |
void |
dump(PrintStream ps)
Dump the raw template in canonical form.
|
void |
dump(Writer out)
Dump the raw template in canonical form.
|
int |
getActualTagSyntax()
Returns the tag syntax the parser has chosen for this template.
|
Configuration |
getConfiguration()
Returns the Configuration object associated with this template.
|
Object |
getCustomLookupCondition()
Gets the custom lookup condition with which this template was found.
|
String |
getDefaultNS() |
String |
getEncoding()
Returns the default character encoding used for reading included files.
|
List |
getImports()
Deprecated.
Should only be used internally, and might will be removed later.
|
Map |
getMacros()
Deprecated.
Should only be used internally, and might will be removed later.
|
String |
getName()
The usually path-like (or URL-like) identifier of the template, or possibly
null for non-stored
templates. |
String |
getNamespaceForPrefix(String prefix) |
static Template |
getPlainTextTemplate(String name,
String content,
Configuration config)
|
static Template |
getPlainTextTemplate(String name,
String sourceName,
String content,
Configuration config)
Creates a
Template that only contains a single block of static text, no dynamic content. |
String |
getPrefixedName(String localName,
String nsURI) |
String |
getPrefixForNamespace(String nsURI) |
freemarker.core.TemplateElement |
getRootTreeNode()
Deprecated.
Should only be used internally, and might will be removed later.
|
String |
getSource(int beginColumn,
int beginLine,
int endColumn,
int endLine)
Returns the template source at the location specified by the coordinates given, or
null if unavailable. |
String |
getSourceName()
The name that was actually used to load this template from the
TemplateLoader (or from other custom
storage mechanism). |
void |
process(Object dataModel,
Writer out)
Executes template, using the data-model provided, writing the generated output
to the supplied
Writer . |
void |
process(Object dataModel,
Writer out,
ObjectWrapper wrapper)
Like
process(Object, Writer) , but overrides the Configurable.getObjectWrapper() . |
void |
process(Object dataModel,
Writer out,
ObjectWrapper wrapper,
TemplateNodeModel rootNode)
Like
process(Object, Writer) , but also sets a (XML-)node to be recursively processed by the template. |
void |
setCustomLookupCondition(Object customLookupCondition)
Mostly only used internally; setter pair of
getCustomLookupCondition() . |
void |
setEncoding(String encoding)
Deprecated.
Should only be used internally, and might will be removed later.
|
String |
toString()
Returns a string representing the raw template
text in canonical form.
|
clone, doAutoImportsAndIncludes, getArithmeticEngine, getAutoFlush, getBooleanFormat, getClassicCompatibleAsInt, getCorrectedNameForUnknownSetting, getCustomAttribute, getCustomAttributeNames, getDateFormat, getDateTimeFormat, getEnvironment, getLocale, getLogTemplateExceptions, getNewBuiltinClassResolver, getNumberFormat, getObjectWrapper, getOutputEncoding, getParent, getSetting, getSettings, getShowErrorTips, getSQLDateAndTimeTimeZone, getTemplateExceptionHandler, getTimeFormat, getTimeZone, getURLEscapingCharset, invalidSettingValueException, isAPIBuiltinEnabled, isClassicCompatible, parseAsImportList, parseAsList, parseAsSegmentedList, removeCustomAttribute, setAPIBuiltinEnabled, setArithmeticEngine, setAutoFlush, setBooleanFormat, setClassicCompatible, setClassicCompatibleAsInt, setCustomAttribute, setDateFormat, setDateTimeFormat, setLocale, setLogTemplateExceptions, setNewBuiltinClassResolver, setNumberFormat, setObjectWrapper, setOutputEncoding, setSetting, setSettings, setSettings, setShowErrorTips, setSQLDateAndTimeTimeZone, setStrictBeanModels, setTemplateExceptionHandler, setTimeFormat, setTimeZone, settingValueAssignmentException, setURLEscapingCharset, unknownSettingException
public static final String DEFAULT_NAMESPACE_PREFIX
public static final String NO_NS_PREFIX
public Template(String name, Reader reader, Configuration cfg) throws IOException
IOException
public Template(String name, String sourceCode, Configuration cfg) throws IOException
Template(name, new StringReader(reader), cfg)
.IOException
public Template(String name, Reader reader, Configuration cfg, String encoding) throws IOException
Template(String, Reader, Configuration)
instead, which doesn't
specify the encoding.Template(name, null,
reader, cfg, encoding)
.IOException
public Template(String name, String sourceName, Reader reader, Configuration cfg) throws IOException
Template
instances instead of re-creating them from the
same source again and again. (and its overloads already do such reuse.
)name
- The path of the template file relatively to the (virtual) directory that you use to store the
templates (except if sourceName
is
differs from it). Shouldn't start with '/'
. Should use '/'
, not '\'
. Check
getName()
to see how the name will be used. The name should be independent of the actual
storage mechanism and physical location as far as possible. Even when the templates are stored
straightforwardly in real files (they often aren't; see TemplateLoader
), the name shouldn't be
an absolute file path. Like if the template is stored in "/www/templates/forum/main.ftl"
, and
you are using "/www/templates/"
as the template root directory via
Configuration.setDirectoryForTemplateLoading(java.io.File)
, then the template name will be
"forum/main.ftl"
.sourceName
- See getSourceName()
for the meaning. Can be null
, in which case
getSourceName()
will return the same as getName()
.reader
- The character stream to read from. It will always be closed (Reader.close()
) by this method.cfg
- The Configuration object that this Template is associated with. If this is null
, the "default"
Configuration
object is used, which is highly discouraged, because it can easily lead to
erroneous, unpredictable behavior. (See more here...
)IOException
public Template(String name, String sourceName, Reader reader, Configuration cfg, String encoding) throws IOException
Template(String, String, Reader, Configuration)
instead, which
doesn't specify the encoding.Template(String, String, Reader, Configuration)
, but also specifies the template's encoding (not
recommended).encoding
- This is the encoding that we are supposed to be using. But it's not really necessary because we have a
Reader
which is already decoded, but it's kept as meta-info. It also has an impact when
#include
-ing/#import
-ing another template from this template, as its default encoding
will be this. But this behavior of said directives is considered to be harmful, and will be probably
phased out. Until that, it's better to leave this on null
, so that the encoding will come from
the Configuration
. Note that if this is non-null
and there's an #ftl
header
with encoding, they must match, or else a Template.WrongEncodingException
is thrown.IOException
public Template(String name, Reader reader) throws IOException
Configuration
instance, which can easily lead to erroneous, unpredictable behavior.
See more here...
.Template(name, reader, null)
.IOException
public static Template getPlainTextTemplate(String name, String content, Configuration config)
public static Template getPlainTextTemplate(String name, String sourceName, String content, Configuration config)
Template
that only contains a single block of static text, no dynamic content.name
- See getName()
for more details.sourceName
- See getSourceName()
for more details. If null
, it will be the same as the name
.content
- the block of text that this template representsconfig
- the configuration to which this template belongspublic void process(Object dataModel, Writer out) throws TemplateException, IOException
Writer
.
For finer control over the runtime environment setup, such as per-HTTP-request configuring of FreeMarker
settings, you may need to use createProcessingEnvironment(Object, Writer)
instead.
dataModel
- the holder of the variables visible from the template (name-value pairs); usually a
Map<String, Object>
or a JavaBean (where the JavaBean properties will be the variables).
Can be any object that the ObjectWrapper
in use turns into a TemplateHashModel
.
You can also use an object that already implements TemplateHashModel
; in that case it won't be
wrapped. If it's null
, an empty data model is used.out
- The Writer
where the output of the template will go. Note that unless you have used
Configurable.setAutoFlush(boolean)
to disable this, Writer.flush()
will be called at the
when the template processing was finished. Writer.close()
is not called.TemplateException
- if an exception occurs during template processingIOException
- if an I/O exception occurs during writing to the writer.public void process(Object dataModel, Writer out, ObjectWrapper wrapper, TemplateNodeModel rootNode) throws TemplateException, IOException
process(Object, Writer)
, but also sets a (XML-)node to be recursively processed by the template.
That node is accessed in the template with .node, #recurse, etc. See the
Declarative XML Processing as a
typical example of recursive node processing.rootNode
- The root node for recursive processing or null
.TemplateException
- if an exception occurs during template processingIOException
- if an I/O exception occurs during writing to the writer.public void process(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException
process(Object, Writer)
, but overrides the Configurable.getObjectWrapper()
.wrapper
- The ObjectWrapper
to be used instead of what Configurable.getObjectWrapper()
provides, or null
if you don't want to override that.TemplateException
IOException
public Environment createProcessingEnvironment(Object dataModel, Writer out, ObjectWrapper wrapper) throws TemplateException, IOException
Environment
object, using this template, the data-model provided as
parameter. You have to call Environment.process()
on the return value to set off the actual rendering.
Use this method if you want to do some special initialization on the Environment
before template
processing, or if you want to read the Environment
after template processing. Otherwise using
process(Object, Writer)
is simpler.
Example:
Environment env = myTemplate.createProcessingEnvironment(root, out, null); env.process();
The above is equivalent with this:
myTemplate.process(root, out);
But with createProcessingEnvironment, you can manipulate the environment before and after the processing:
Environment env = myTemplate.createProcessingEnvironment(root, out); env.setLocale(myUsersPreferredLocale); env.setTimeZone(myUsersPreferredTimezone); env.process(); // output is rendered here TemplateModel x = env.getVariable("x"); // read back a variable set by the template
dataModel
- the holder of the variables visible from all templates; see process(Object, Writer)
for
more details.wrapper
- The ObjectWrapper
to use to wrap objects into TemplateModel
instances. Normally you left it null
, in which case Configurable.getObjectWrapper()
will be
used.out
- The Writer
where the output of the template will go; see process(Object, Writer)
for
more details.Environment
object created for processing. Call Environment.process()
to process the
template.TemplateException
- if an exception occurs while setting up the Environment object.IOException
- if an exception occurs doing any auto-importspublic Environment createProcessingEnvironment(Object dataModel, Writer out) throws TemplateException, IOException
TemplateException
IOException
public String toString()
public String getName()
null
for non-stored
templates. It usually looks like a relative UN*X path; it should use /
, not \
, and shouldn't
start with /
(but there are no hard guarantees). It's not a real path in a file-system, it's just a name
that a TemplateLoader
used to load the backing resource (in simple cases; actually that name is
getSourceName()
, but see it there). Or, it can also be a name that was never used to load the template
(directly created with Template(String, Reader, Configuration)
). Even if the templates are stored
straightforwardly in files, this is relative to the base directory of the TemplateLoader
. So it really
could be anything, except that it has importance in these situations:
Relative paths to other templates in this template will be resolved relatively to the directory part of this.
Like if the template name is "foo/this.ftl"
, then <#include "other.ftl">
gets the template with
name "foo/other.ftl"
.
You should not use this name to indicate error locations, or to find the actual templates in general, because
localized lookup, acquisition and other lookup strategies can transform names before they get to the
TemplateLoader
(the template storage) mechanism. Use getSourceName()
for these purposes.
Some frameworks use URL-like template names like "someSchema://foo/bar.ftl"
. FreeMarker understands this
notation, so an absolute path like "/baaz.ftl"
in that template will be resolved too
"someSchema://baaz.ftl"
.
public String getSourceName()
TemplateLoader
(or from other custom
storage mechanism). This is what should be shown in error messages as the error location. This is usually the
same as getName()
, except when localized lookup, template acquisition (*
step in the name), or
other TemplateLookupStrategy
transforms the requested name (getName()
) to a different final
TemplateLoader
-level name. For example, when you get a template with name "foo.ftl"
then because
of localized lookup, it's possible that something like "foo_en.ftl"
will be loaded behind the scenes.
While the template name will be still the same as the requested template name ("foo.ftl"
), errors should
point to "foo_de.ftl"
. Note that relative paths are always resolved relatively to the name
, not
to the sourceName
.public Configuration getConfiguration()
public void setEncoding(String encoding)
public String getEncoding()
public Object getCustomLookupCondition()
customLookupCondition
parameter of Configuration.getTemplate(String, java.util.Locale, Object, String, boolean, boolean)
for
more explanation.public void setCustomLookupCondition(Object customLookupCondition)
getCustomLookupCondition()
. This meant to be called directly
after instantiating the template with its constructor, after a successfull lookup that used this condition. So
this should only be called from code that deals with creating new Template
objects, like from
TemplateCache
.public int getActualTagSyntax()
Configuration.SQUARE_BRACKET_TAG_SYNTAX
or Configuration.ANGLE_BRACKET_TAG_SYNTAX
. If the syntax
couldn't be determined (like because there was no tags in the template, or it was a plain text template), this
returns whatever the default is in the current configuration, so it's maybe
Configuration.AUTO_DETECT_TAG_SYNTAX
.public void dump(PrintStream ps)
public void dump(Writer out) throws IOException
IOException
public void addMacro(freemarker.core.Macro macro)
public void addImport(freemarker.core.LibraryLoad ll)
public String getSource(int beginColumn, int beginLine, int endColumn, int endLine)
null
if unavailable.beginColumn
- the first column of the requested source, 1-basedbeginLine
- the first line of the requested source, 1-basedendColumn
- the last column of the requested source, 1-basedendLine
- the last line of the requested source, 1-basedTemplateObject.getSource()
public freemarker.core.TemplateElement getRootTreeNode()
public Map getMacros()
public List getImports()
public void addPrefixNSMapping(String prefix, String nsURI)
public String getDefaultNS()
public String getNamespaceForPrefix(String prefix)
public String getPrefixForNamespace(String nsURI)
public String getPrefixedName(String localName, String nsURI)
public TreePath containingElements(int column, int line)
TemplateElement
s containing the given column and line numbers.