Monday, July 25, 2011

What is FreeMarker?

FreeMarker is a "template engine"; a generic tool to generate text output (anything from HTML to autogenerated source code) based on templates. It's a Java package, a class library for Java programmers. It's not an application for end-users in itself, but something that programmers can embed into their products.  

FreeMarker is designed to be practical for the generation of HTML Web pages, particularly by servlet-based applications following the MVC (Model View Controller) pattern. The idea behind using the MVC pattern for dynamic Web pages is that you separate the designers (HTML authors) from the programmers. Everybody works on what they are good at. Designers can change the appearance of a page without programmers having to change or recompile code, because the application logic (Java programs) and page design (FreeMarker templates) are separated. Templates do not become polluted with complex program fragments. This separation is useful even for projects where the programmer and the HTML page author is the same person, since it helps to keep the application clear and easily maintainable.

Although FreeMarker has some programming capabilities, it is not a full-blown programming language like PHP. Instead, Java programs prepare the data to be displayed (like issue SQL queries), and FreeMarker just generates textual pages that display the prepared data using templates. 


FreeMarker is not a Web application framework. It is suitable as a component in a Web application framework, but the FreeMarker engine itself knows nothing about HTTP or servlets. It simply generates text. As such, it is perfectly usable in non-web application environments as well. Note, however, that we provide out-of-the-box solutions for using FreeMarker as the view component of Model 2 frameworks (e.g. Struts), which also let you use JSP taglibs in the templates.  

FreeMarker is Free, with BSD-style license. It is OSI Certified Open Source Software. OSI Certified is a certification mark of the Open Source Initiative

General purpose

  • Can be used to generate any kind of text: HTML, XML, RTF, Java source code, etc.
  • Easy to embed into your product: Lightweight. Does not require servlet environment (does not depend on javax.servlet classes).
  • Pluggable template loader: you can load templates from any sources; local files, database, etc.
  • You can do whatever you want with the generated text: store it in a local file, send it as e-mail, send it back to a Web browser from a Web application, etc.

Powerful template language

  • All usual directives: include, if/elseif/else, loop constructs.
  • Creating and changing variables in templates.
  • Can use complex expressions to specify values almost everywhere.
    • String operations: concatenation, sub-string, uppercase, capitalize, escaping, etc.
    • Decimal precision arithmetic calculations
    • Boolean arithmetic
    • Reading array and associative array elements
    • Array and associative array literals
    • You can add your own functions (methods) for special calculations.
  • Macros with named and positional parameters and with nested content (body). For example:
    <@myMacro color="red" width=2>...</@myMacro>
  • Name-spaces to help build and maintain reusable macro libraries or to divide big projects into separated modules, without worrying about name clashes.
  • Output transformation blocks. Do transformations as HTML-escaping, compression, syntax-highlight etc. on the output generated by the nested template fragment. You can define your own transformations.

Versatile data model

FreeMarker does not work through direct reflection on Java objects; the Java objects are exposed to the template as variables through pluggable object wrappers. Thus, you can show the objects (Java beans, XML documents, SQL query result sets, etc.) in an abstract, tailored way for the template authors, without bothering them with technical details.


  • Built-in constructs in the template language to handle typical Web related tasks like HTML-escaping.
  • Can be integrated with "Model 2" Web application frameworks out-of-the-box as JSP replacement.
  • Supports JSP taglibs, up to JSP 2.1 currently, except that the JSP 2 "tag files" (i.e., when custom tags are implemented in JSP language rather than as Java classes) are not supported.
  • Designed for MVC pattern: separate visual design from application logic, separate page designers from programmers.

Internationalization/localization aware

  • Charset aware (uses UNICODE internally).
  • Locale sensitive number formatting.
  • Locale sensitive date and time formatting.
  • Non-US characters can be used in identifiers (as variable names).
  • Multiple variations of the same template for different languages.

Powerful XML Processing Capabilities

  • <#recurse> and <#visit> directives (new in version 2.3) for recursively walking an XML tree
  • Clean, intuitive XML object model accessible from template.

Comparing with other products

You might also be interested what distinguish FreeMarker from Apache Velocity.
FreeMarker 2.3 often can be used as an alternative to XSLT.  


import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import freemarker.ext.beans.BeansWrapper;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.TemplateException;
import freemarker.template.TemplateHashModel;
import freemarker.template.TemplateModelException;

public class FreeMarkerExecuter {

    private freemarker.template.Template template;

    public FreeMarkerExecuter(Map<String, Object> sharedVariables,
            String templatePath, String templateName) throws Exception {
        this.initFreemaker(sharedVariables, templatePath, templateName);

    protected void initFreemaker(Map<String, Object> sharedVariables,
            String templatePath, String templateName) throws Exception {
        try {
            if (templatePath == null)
                throw new Exception("templatePath is null");
            Configuration fmConfig = new freemarker.template.Configuration();
            if (templatePath == null)
                fmConfig.setClassForTemplateLoading(this.getClass(), "");
                fmConfig.setDirectoryForTemplateLoading(new File(templatePath));
            fmConfig.setObjectWrapper(new DefaultObjectWrapper());
            if (sharedVariables == null) {
                sharedVariables = new HashMap<String, Object>();
            sharedVariables.put("statics", BeansWrapper.getDefaultInstance().getStaticModels());
            Iterator<String> iter = sharedVariables.keySet().iterator();
            while (iter.hasNext()) {
                String key =;
                fmConfig.setSharedVariable(key, sharedVariables.get(key));
            fmConfig.setWhitespaceStripping(true); // zaten true idi
            template = fmConfig.getTemplate(templateName);
        } catch (IOException e) {
            throw new Exception(e);
        } catch (TemplateModelException e) {
            throw new Exception(e);

    public String execute(Map<String, Object> dataModel) throws Exception {
        try {
            StringWriter sw = new StringWriter();
            template.process(dataModel, sw);
            return sw.toString();
        } catch (TemplateException e) {
            throw new Exception(e);
        } catch (IOException e) {
            throw new Exception(e);

First call contructor method, give sharedVariables (common shared variables, if dont use it, can give null ), template path and template file, after that call execute give dataModel (local variables for execution) 

Simple demo : 
FreeMarkerExecuter fme = new FreeMarkerExecuter(null, "c:\", "test.ftl");
Map<String, Object> dataModel = new HashMap();
dataModel.put("var1", "test");
dataModel.put("var2",  "test2");
String result = fme.execute(dataModel);

test.ftl (use freemarker template language)
Hello World ! ${var1}  ${var2}
Hello World ! test test2


  1. dataModel.put("var2", "test2");

    1. Thanks. I've fixed it :)