Class Template


  • 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) (and its overloads) 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. If some templates need different settings that those coming from the shared Configuration, and you are using Configuration.getTemplate(String) (or its overloads), then use Configuration.setTemplateConfigurations(freemarker.cache.TemplateConfigurationFactory) to achieve that.

    • Field Detail

      • DEFAULT_NAMESPACE_PREFIX

        public static final java.lang.String DEFAULT_NAMESPACE_PREFIX
        See Also:
        Constant Field Values
    • Constructor Detail

      • Template

        public Template​(java.lang.String name,
                        java.lang.String sourceName,
                        java.io.Reader reader,
                        Configuration cfg)
                 throws java.io.IOException
        Constructs a template from a character stream. Note that this is a relatively expensive operation; where higher performance matters, you should re-use (cache) Template instances instead of re-creating them from the same source again and again. (and its overloads already do such reuse.)
        Parameters:
        name - The path of the template file relatively to the (virtual) directory that you use to store the templates (except if sourceName 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". The name can be null (should be used for template made on-the-fly instead of being loaded from somewhere), in which case relative paths in it will be relative to the template root directory (and here again, it's the TemplateLoader that knows what that "physically" means).
        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 (this is for backward compatibility; later major versions may discontinue this behavior). The Reader need not be buffered, because this method ensures that it will be read in few kilobyte chunks, not byte by byte.
        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...)
        Throws:
        java.io.IOException
        Since:
        2.3.22
      • Template

        public Template​(java.lang.String name,
                        java.lang.String sourceName,
                        java.io.Reader reader,
                        Configuration cfg,
                        java.lang.String encoding)
                 throws java.io.IOException
        Same as Template(String, String, Reader, Configuration), but also specifies the template's encoding (not recommended).
        Parameters:
        encoding - This is the encoding that we are supposed to be using. At the first glance it's unnecessary because we already have a Reader (so decoding with the charset has already happened), however, if this is non-null and there's an #ftl header with encoding parameter, they must match, or else a Template.WrongEncodingException is thrown. Thus, it should be set if to decode the template, we were using an encoding (a charset), otherwise it should be null. It's also kept as meta-info (returned by getEncoding()). It also has an impact when #include-ing or #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.
        Throws:
        java.io.IOException
        Since:
        2.3.22
      • Template

        @Deprecated
        public Template​(java.lang.String name,
                        java.io.Reader reader)
                 throws java.io.IOException
        Deprecated.
        This constructor uses the "default" Configuration instance, which can easily lead to erroneous, unpredictable behavior. See more here....
        Throws:
        java.io.IOException
    • Method Detail

      • getPlainTextTemplate

        public static Template getPlainTextTemplate​(java.lang.String name,
                                                    java.lang.String sourceName,
                                                    java.lang.String content,
                                                    Configuration config)
        Creates (not "get"-s) a Template that only contains a single block of static text, no dynamic content.
        Parameters:
        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 represents
        config - the configuration to which this template belongs
        Since:
        2.3.22
      • process

        public void process​(java.lang.Object dataModel,
                            java.io.Writer out)
                     throws TemplateException,
                            java.io.IOException
        Executes template, using the data-model provided, writing the generated output to the supplied 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.

        Parameters:
        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. Can't be null.
        Throws:
        TemplateException - if an exception occurs during template processing
        java.io.IOException - if an I/O exception occurs during writing to the writer.
      • process

        public void process​(java.lang.Object dataModel,
                            java.io.Writer out,
                            ObjectWrapper wrapper,
                            TemplateNodeModel rootNode)
                     throws TemplateException,
                            java.io.IOException
        Like 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.
        Parameters:
        rootNode - The root node for recursive processing or null.
        Throws:
        TemplateException - if an exception occurs during template processing
        java.io.IOException - if an I/O exception occurs during writing to the writer.
      • createProcessingEnvironment

        public Environment createProcessingEnvironment​(java.lang.Object dataModel,
                                                       java.io.Writer out,
                                                       ObjectWrapper wrapper)
                                                throws TemplateException,
                                                       java.io.IOException
        Creates a 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
        Parameters:
        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.
        Returns:
        the Environment object created for processing. Call Environment.process() to process the template.
        Throws:
        TemplateException - if an exception occurs while setting up the Environment object.
        java.io.IOException - if an exception occurs doing any auto-imports
      • toString

        public java.lang.String toString()
        Returns a string representing the raw template text in canonical form.
        Overrides:
        toString in class java.lang.Object
      • getName

        public java.lang.String getName()
        The usually path-like (or URL-like) identifier of the template, or possibly 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".

      • getSourceName

        public java.lang.String getSourceName()
        The name that was actually used to load this template from the 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.
        Since:
        2.3.22
      • getConfiguration

        public Configuration getConfiguration()
        Returns the Configuration object associated with this template.
      • setEncoding

        @Deprecated
        public void setEncoding​(java.lang.String encoding)
        Deprecated.
        Should only be used internally, and might will be removed later.
        Parameters:
        encoding - The encoding that was used to read this template. When this template #include-s or #import-s another template, by default it will use this encoding for those. For backward compatibility, this can be null, which will unset this setting.
      • getEncoding

        public java.lang.String getEncoding()
        The encoding that was (allegedly) used to read this template; also the the default character encoding used for reading files included from this template. Possibly null, in which case you are supposed to use Configuration.getEncoding(Locale).
      • setCustomLookupCondition

        public void setCustomLookupCondition​(java.lang.Object customLookupCondition)
        Mostly only used internally; setter pair of 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.
        Since:
        2.3.22
      • dump

        public void dump​(java.io.PrintStream ps)
        Dump the raw template in canonical form.
      • dump

        public void dump​(java.io.Writer out)
                  throws java.io.IOException
        Dump the raw template in canonical form.
        Throws:
        java.io.IOException
      • addMacro

        @Deprecated
        public void addMacro​(freemarker.core.Macro macro)
        Deprecated.
        Should only be used internally, and might will be removed later.
        Called by code internally to maintain a table of macros
      • addImport

        @Deprecated
        public void addImport​(freemarker.core.LibraryLoad ll)
        Deprecated.
        Should only be used internally, and might will be removed later.
        Called by code internally to maintain a list of imports
      • getSource

        public 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. A strange legacy in the behavior of this method is that it replaces tab characters with spaces according the value of getParserConfiguration()/ParserConfiguration.getTabSize() (which usually comes from Configuration.getTabSize()), because tab characters move the column number with more than 1 in error messages. However, if you set the tab size to 1, this method leaves the tab characters as is.
        Parameters:
        beginColumn - the first column of the requested source, 1-based
        beginLine - the first line of the requested source, 1-based
        endColumn - the last column of the requested source, 1-based
        endLine - the last line of the requested source, 1-based
        See Also:
        TemplateObject.getSource()
      • getRootTreeNode

        @Deprecated
        public freemarker.core.TemplateElement getRootTreeNode()
        Deprecated.
        Should only be used internally, and might will be removed later.
      • getMacros

        @Deprecated
        public java.util.Map getMacros()
        Deprecated.
        Should only be used internally, and might will be removed later.
      • getImports

        @Deprecated
        public java.util.List getImports()
        Deprecated.
        Should only be used internally, and might will be removed later.
      • addPrefixNSMapping

        @Deprecated
        public void addPrefixNSMapping​(java.lang.String prefix,
                                       java.lang.String nsURI)
        Deprecated.
        Should only be used internally, and might will be removed later.
        This is used internally.
      • getDefaultNS

        public java.lang.String getDefaultNS()
      • getNamespaceForPrefix

        public java.lang.String getNamespaceForPrefix​(java.lang.String prefix)
        Returns:
        the NamespaceUri mapped to this prefix in this template. (Or null if there is none.)
      • getPrefixForNamespace

        public java.lang.String getPrefixForNamespace​(java.lang.String nsURI)
        Returns:
        the prefix mapped to this nsURI in this template. (Or null if there is none.)
      • getPrefixedName

        public java.lang.String getPrefixedName​(java.lang.String localName,
                                                java.lang.String nsURI)
        Returns:
        the prefixed name, based on the ns_prefixes defined in this template's header for the local name and node namespace passed in as parameters.
      • containingElements

        @Deprecated
        public javax.swing.tree.TreePath containingElements​(int column,
                                                            int line)
        Deprecated.
        Should only be used internally, and might will be removed later.
        Returns:
        an array of the TemplateElements containing the given column and line numbers.