Template loaders
Template loaders are objects that load raw textual data based
          on abstract template paths like "index.ftl" or
          "products/catalog.ftl". It's up to the concrete
          template loader if from where and how the template
          "files" are loaded. They could be real files inside a
          specified directory, or values in a data base table, or
          String-s in a Java Map, etc. When you call
          cfg.getTemplate (where cfg is
          a Configuration instance), FreeMarker asks the
          template loader (cfg.getTemplateLoader) to return
          the text for the given template path, and then FreeMarker parses
          that text as template. It doesn't care or even know if the template
          is a real file or not, and where it is physically; those details are
          only known by the template loader.
Built-in template loaders
You can set up the three most common template loading
            mechanism in the Configuration using the
            following convenience methods:
- 
                
void setDirectoryForTemplateLoading(File dir): Sets a directory on the file system from which to load templates. Template names (template paths) will be interpreted relatively to this physical directory. It won't let you load files outside this directory. - 
                
void setClassForTemplateLoading(Class cl, String basePackagePath)andvoid setClassLoaderForTemplateLoading(ClassLoader classLoader, String basePackagePath): These are for when you want to load templates via the same mechanism with which Java loads classes (from the class-path, as they used to say vaguely). This is very likely be the preferred means of loading templates for production code, as it allows you to keep everything inside the deploymentjarfiles. The first parameter decides which JavaClassLoaderwill be used. The second parameter specifies the package that contains the templates, in/-separated format. Note that if you don't start it with/, it will be interpreted relatively to the package of theClassparameter. - 
                
void setServletContextForTemplateLoading(Object servletContext, String path): Takes the context of your Servlet-based web application, and a base path, which is interpreted relative to the web application root directory (that's the parent of theWEB-INFdirectory). Note that we refer to "directory" here although this loading method works even for unpacked.warfiles, since it usesServletContext.getResource()to access the templates. If you omit the second parameter (or use""), you can simply store the static files (.html,.jpg, etc.) mixed with the.ftlfiles. Of course, you must set up a Servlet for the*.ftl,*.ftlh,*.ftlxuri-patterns inWEB-INF/web.xmlfor this, otherwise the client will get the raw templates as is! To avoid a such accident, many prefers storing the templates somewhere inside theWEB-INFdirectory, which is never visitable directly. This mechanism will very likely be the preferred means of loading templates for servlet applications, since the templates can be updated without restarting the web application, while this often doesn't work with the class-loader mechanism. 
If you want to use a custom
            TemplateLoader implementation, or need to set
            up some extra settings of a built-in template loader, you need to
            instantiate the TemplateLoader object yourself,
            and then call
            Configuration.setTemplateLoader(TemplateLoader):
WebappTemplateLoader templateLoader = new WebappTemplateLoader(servletContext, "WEB-INF/templates"); templateLoader.setURLConnectionUsesCaches(false); templateLoader.setAttemptFileAccess(false); cfg.setTemplateLoader(templateLoader);
Loading templates from multiple locations
If you need to load templates from multiple locations, you
            have to instantiate the template loader objects for every
            location, wrap them into a MultiTemplateLoader,
            and finally pass that loader to the
            setTemplateLoader(TemplateLoader loader) method
            of Configuration. Here's an example for loading
            templates from two distinct directories and with the
            class-loader:
import freemarker.cache.*; // template loaders live in this package
...
FileTemplateLoader ftl1 = new FileTemplateLoader(new File("/tmp/templates"));
FileTemplateLoader ftl2 = new FileTemplateLoader(new File("/usr/data/templates"));
ClassTemplateLoader ctl = new ClassTemplateLoader(getClass(), "/com/example/templates");
MultiTemplateLoader mtl = new MultiTemplateLoader(new TemplateLoader[] { ftl1, ftl2, ctl });
cfg.setTemplateLoader(mtl);    Now FreeMarker will try to load templates from
            /tmp/templates directory, and if it does not
            find the requested template there, it will try to load that from
            /usr/data/templates, and if it still does not
            find the requested template, then it tries to load it from the
            com.example.templates Java package.
Loading templates from other sources
If none of the built-in class loaders fit your needs, you
            can write your own class that implements the
            freemarker.cache.TemplateLoader interface and
            pass it to the setTemplateLoader(TemplateLoader
            loader) method of Configuration.
            Please read the API JavaDoc for more information.
If your template source accesses the templates through an
            URL, you needn't implement a TemplateLoader
            from scratch; you can choose to subclass
            freemarker.cache.URLTemplateLoader instead and
            just implement the URL getURL(String
            templateName) method.
The template name (template path)
It is up to the template loader how it interprets template
            names (also known as template paths). But to work together with
            other components there are restrictions regarding the format of
            the path. In general, it is strongly recommended that template
            loaders use URL-style paths. The path must not use
            / (path step separator) character, nor the
            . (same-directory) and ..
            (parent directory) path steps with other meaning than they have in
            URL paths (or in UN*X paths). The * (asterisk)
            step is also reserved, and used for "template
            acquisition" feature of FreeMarker.
:// (or with
            template_name_format setting set to
            DEFAULT_2_4_0, the : (colon)
            character) is reserved for specifying a scheme part, similarly as
            it works with URI-s. For example
            someModule://foo/bar.ftl uses the
            someModule, or assuming the
            DEFAULT_2_4_0 format,
            classpath:foo/bar.ftl uses the
            classpath scheme. Interpreting the scheme part
            is completely up to the TemplateLoader. (The
            FreeMarker core is only aware of the idea of schemes because
            otherwise it couldn't resolve relative template names
            properly.)
FreeMarker always normalizes the paths before passing them
            to the TemplateLoader, so the paths don't
            contain /../ or such, and are relative to the
            imaginary template root directory (that is, they don't start with
            /). They don't contain the *
            step either, as template acquisition happens in an earlier stage.
            Furthermore, with template_name_format setting
            set to DEFAULT_2_4_0, multiple consecutive
            /-s will be normalized to a single
            / (unless they are part of the
            :// scheme separator).
Note that FreeMarker template path should always uses slash (not backslash) regardless of the host OS.
Template caching
FreeMarker caches templates (assuming you use the
          Configuration methods to create
          Template objects). This means that when you call
          getTemplate, FreeMarker not only returns the
          resulting Template object, but stores it in a
          cache, so when next time you call getTemplate
          with the same (or equivalent) path, it just returns the cached
          Template instance, and will not load and parse
          the template file again.
If you change the template file, then FreeMarker will re-load
          and re-parse the template automatically when you get the template
          next time. However, since always checking for changes can be burden
          for a system that processes lot of templates, there is a
          Configuration level setting called "update
          delay" (defaults is 5 seconds). Until this much time has
          elapsed since the last checking for a newer version, FreeMarker will
          not check again if the template was changed. If you want to see the
          changes without delay, set this setting to 0. Note that some
          template loaders won't see that a template was changed because of
          the underlying storage mechanism doesn't support that; for example,
          class-loader based template loaders may have this problem.
A template will be removed from the cache if you call
          getTemplate and FreeMarker realizes that the
          template file has been removed meanwhile. Also, if the JVM thinks
          that it begins to run out of memory, by default it can arbitrarily
          drop templates from the cache. Furthermore, you can empty the cache
          manually with the clearTemplateCache method of
          Configuration. You can also drop selected
          template from the cache with
          removeTemplateFromCache; this can be also
          utilized to force re-loading a template regardless of the
          "update delay" setting.
The actual strategy of when a cached template should be thrown
          away is pluggable with the cache_storage setting,
          by which you can plug any CacheStorage
          implementation. For most users
          freemarker.cache.MruCacheStorage will be
          sufficient. This cache storage implements a two-level Most Recently
          Used cache. In the first level, items are strongly referenced up to
          the specified maximum (strongly referenced items can't be dropped by
          the JVM, as opposed to softly referenced items). When the maximum is
          exceeded, the least recently used item is moved into the second
          level cache, where they are softly referenced, up to another
          specified maximum. The size of the strong and soft parts can be
          specified with the constructor. For example, set the size of the
          strong part to 20, and the size of soft part to 250:
cfg.setCacheStorage(new freemarker.cache.MruCacheStorage(20, 250))
Or, since MruCacheStorage is the default
          cache storage implementation:
cfg.setSetting(Configuration.CACHE_STORAGE_KEY, "strong:20, soft:250");
When you create a new Configuration object,
          initially it uses an MruCacheStorage where
          strongSizeLimit is 0, and
          softSizeLimit is
          Integer.MAX_VALUE (that is, in practice,
          infinite). Depending on how smart the JVM is, using non-0
          strongSizeLimit is maybe a safer option, as with
          only softly referenced items the JVM could even throw the most
          frequently used templates when there's a resource shortage, which
          then have to be re-loaded and re-parsed, burdening the system even
          more.
