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 |
Configurable.UnknownSettingException
Modifier and Type | Field and Description |
---|---|
static java.lang.String |
DEFAULT_NAMESPACE_PREFIX |
static java.lang.String |
NO_NS_PREFIX |
ARITHMETIC_ENGINE_KEY, AUTO_FLUSH_KEY, BOOLEAN_FORMAT_KEY, CLASSIC_COMPATIBLE_KEY, DATE_FORMAT_KEY, DATETIME_FORMAT_KEY, LOCALE_KEY, NEW_BUILTIN_CLASS_RESOLVER_KEY, NUMBER_FORMAT_KEY, OBJECT_WRAPPER_KEY, OUTPUT_ENCODING_KEY, STRICT_BEAN_MODELS, TEMPLATE_EXCEPTION_HANDLER_KEY, TIME_FORMAT_KEY, TIME_ZONE_KEY, URL_ESCAPING_CHARSET_KEY
Constructor and Description |
---|
Template(java.lang.String name,
java.io.Reader reader)
Deprecated.
This constructor uses the "default"
Configuration
instance, which can easily lead to erroneous, unpredictable behavior.
See more here... . |
Template(java.lang.String name,
java.io.Reader reader,
Configuration cfg)
Constructs a template from a character stream.
|
Template(java.lang.String name,
java.io.Reader reader,
Configuration cfg,
java.lang.String encoding)
Deprecated.
Use
Template(String, Reader, Configuration) instead. |
Template(java.lang.String name,
java.lang.String sourceCode,
Configuration cfg)
Convenience constructor for
Template(name, new StringReader(reader), cfg) . |
Modifier and Type | Method and Description |
---|---|
void |
addImport(freemarker.core.LibraryLoad ll)
Called by code internally to maintain
a list of imports
|
void |
addMacro(freemarker.core.Macro macro)
Called by code internally to maintain
a table of macros
|
void |
addPrefixNSMapping(java.lang.String prefix,
java.lang.String nsURI)
This is used internally.
|
javax.swing.tree.TreePath |
containingElements(int column,
int line) |
Environment |
createProcessingEnvironment(java.lang.Object dataModel,
java.io.Writer out)
|
Environment |
createProcessingEnvironment(java.lang.Object dataModel,
java.io.Writer out,
ObjectWrapper wrapper)
Creates a
Environment object, using this template, the data-model provided as
parameter. |
void |
dump(java.io.PrintStream ps)
Dump the raw template in canonical form.
|
void |
dump(java.io.Writer out)
Dump the raw template in canonical form.
|
int |
getActualTagSyntax()
Returns the tag syntax the parser has chosen for this template:
Configuration.SQUARE_BRACKET_TAG_SYNTAX
or Configuration.ANGLE_BRACKET_TAG_SYNTAX . |
Configuration |
getConfiguration()
Returns the Configuration object associated with this template.
|
java.lang.String |
getDefaultNS() |
java.lang.String |
getEncoding()
Returns the character encoding used for reading included files.
|
java.util.List |
getImports() |
java.util.Map |
getMacros() |
java.lang.String |
getName()
The usually path-like (or URL-like) identifier of the template, or possibly
null for non-stored
templates. |
java.lang.String |
getNamespaceForPrefix(java.lang.String prefix) |
static Template |
getPlainTextTemplate(java.lang.String name,
java.lang.String content,
Configuration config)
Returns a trivial template, one that is just a single block of
plain text, no dynamic content.
|
java.lang.String |
getPrefixedName(java.lang.String localName,
java.lang.String nsURI) |
java.lang.String |
getPrefixForNamespace(java.lang.String nsURI) |
freemarker.core.TemplateElement |
getRootTreeNode() |
java.lang.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. |
void |
process(java.lang.Object dataModel,
java.io.Writer out)
Executes template, using the data-model provided, writing the generated output
to the supplied
Writer . |
void |
process(java.lang.Object dataModel,
java.io.Writer out,
ObjectWrapper wrapper)
Like
process(Object, Writer) , but overrides the Configurable.getObjectWrapper() . |
void |
process(java.lang.Object dataModel,
java.io.Writer out,
ObjectWrapper wrapper,
TemplateNodeModel rootNode)
Like
process(Object, Writer) , but also sets a (XML-)node to be recursively processed by the template. |
void |
setEncoding(java.lang.String encoding)
Sets the character encoding to use for
included files.
|
java.lang.String |
toString()
Returns a string representing the raw template
text in canonical form.
|
clone, doAutoImportsAndIncludes, getArithmeticEngine, getAutoFlush, getBooleanFormat, getClassicCompatibleAsInt, getCustomAttribute, getCustomAttributeNames, getDateFormat, getDateTimeFormat, getEnvironment, getLocale, getNewBuiltinClassResolver, getNumberFormat, getObjectWrapper, getOutputEncoding, getParent, getSetting, getSettings, getTemplateExceptionHandler, getTimeFormat, getTimeZone, getURLEscapingCharset, invalidSettingValueException, isClassicCompatible, parseAsImportList, parseAsList, parseAsSegmentedList, removeCustomAttribute, setArithmeticEngine, setAutoFlush, setBooleanFormat, setClassicCompatible, setClassicCompatibleAsInt, setCustomAttribute, setDateFormat, setDateTimeFormat, setLocale, setNewBuiltinClassResolver, setNumberFormat, setObjectWrapper, setOutputEncoding, setSetting, setSettings, setSettings, setStrictBeanModels, setTemplateExceptionHandler, setTimeFormat, setTimeZone, setURLEscapingCharset, unknownSettingException
public static final java.lang.String DEFAULT_NAMESPACE_PREFIX
public static final java.lang.String NO_NS_PREFIX
public Template(java.lang.String name, java.io.Reader reader, Configuration cfg) throws java.io.IOException
Template
instances instead of re-creating them from
the same source again and again.name
- the path of the template file relatively to the (virtual) directory that you use to store
the templates. 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"
.reader
- the character stream to read from. It will always be closed (Reader.close()
).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...
)java.io.IOException
public Template(java.lang.String name, java.lang.String sourceCode, Configuration cfg) throws java.io.IOException
Template(name, new StringReader(reader), cfg)
.java.io.IOException
public Template(java.lang.String name, java.io.Reader reader, Configuration cfg, java.lang.String encoding) throws java.io.IOException
Template(String, Reader, Configuration)
instead.Template(String, Reader, Configuration)
, but also specifies the template's encoding.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.java.io.IOException
public Template(java.lang.String name, java.io.Reader reader) throws java.io.IOException
Configuration
instance, which can easily lead to erroneous, unpredictable behavior.
See more here...
.Template(name, reader, null)
.java.io.IOException
public static Template getPlainTextTemplate(java.lang.String name, java.lang.String content, Configuration config)
name
- the path of the template file relative to the directory what you use to store
the templates. See getName()
for more details.content
- the block of text that this template representsconfig
- the configuration to which this template belongspublic void process(java.lang.Object dataModel, java.io.Writer out) throws TemplateException, java.io.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 processingjava.io.IOException
- if an I/O exception occurs during writing to the writer.public void process(java.lang.Object dataModel, java.io.Writer out, ObjectWrapper wrapper, TemplateNodeModel rootNode) throws TemplateException, java.io.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 processingjava.io.IOException
- if an I/O exception occurs during writing to the writer.public void process(java.lang.Object dataModel, java.io.Writer out, ObjectWrapper wrapper) throws TemplateException, java.io.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
java.io.IOException
public Environment createProcessingEnvironment(java.lang.Object dataModel, java.io.Writer out, ObjectWrapper wrapper) throws TemplateException, java.io.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.java.io.IOException
- if an exception occurs doing any auto-importspublic Environment createProcessingEnvironment(java.lang.Object dataModel, java.io.Writer out) throws TemplateException, java.io.IOException
TemplateException
java.io.IOException
public java.lang.String toString()
toString
in class java.lang.Object
public java.lang.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. 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".
It's shown in error messages. So it should be something based on which the user can find the template.
Some tools, like an IDE plugin, uses this to identify (and find) templates.
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 Configuration getConfiguration()
public void setEncoding(java.lang.String encoding)
public java.lang.String getEncoding()
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), this returns whatever the default is in the current configuration.public void dump(java.io.PrintStream ps)
public void dump(java.io.Writer out) throws java.io.IOException
java.io.IOException
public void addMacro(freemarker.core.Macro macro)
public void addImport(freemarker.core.LibraryLoad ll)
public java.lang.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 java.util.Map getMacros()
public java.util.List getImports()
public void addPrefixNSMapping(java.lang.String prefix, java.lang.String nsURI)
public java.lang.String getDefaultNS()
public java.lang.String getNamespaceForPrefix(java.lang.String prefix)
public java.lang.String getPrefixForNamespace(java.lang.String nsURI)
public java.lang.String getPrefixedName(java.lang.String localName, java.lang.String nsURI)
public javax.swing.tree.TreePath containingElements(int column, int line)
column
- the columnline
- the line