FreeMarker Tutorial. This tutorial explains how can you define FreeMarker templates and how can yous generate output based on these templates. It also demonstrates the usage of macros.

i. Introduction to FreeMarker

FreeMarker is a Coffee-based template engine which can be used in stand-alone or servlet-based Java programs.

In FreeMarker you ascertain templates, which are text files that contain the desired output, except that they contain placeholders like ${proper noun}, and even some logic similar conditionals, loops, etc. In your Java program you supply the actual values for these placeholders and the final output is generated based on this input.

The input of templates is a agglomeration of named variables that you usually provide as a Map<String, Object> (the Map entries will be the variables) or as a JavaBean (the JavaBean properties volition be the variables). The variable values tin can be unproblematic strings, numbers and such primitive values, but likewise lists, maps, or capricious Java objects whose methods you can call from the template. Note that when accessing JavaBean properties, myObject.myProperty syntax should exist used instead of myObject.getMyProperty().

The output of templates is written into a Author that you lot provide, so it can get into a HTTP response (for dynamic web pages), into a local file, into a String, etc.

It is configurable from where FreeMarker reads the templates; usually used options are loading from a file-system directory, from the course-path, from the servlet context ( Web-INF/templates or such), or even from a database table. It'due south also possible to "load" templates directly from String objects.

ii. Installation of FreeMarker

To utilize FreeMarker download the latest version of it from the following webpage and add it to the classpath of your Coffee projection.

                http://freemarker.org/freemarkerdownload.html              

3. Eclipse Integration

FreeMarker code completion and syntax highlighting is part of the JBoss Tools. Add the following update site to your Eclipse installation via

                http://download.jboss.org/jbosstools/updates/stable/kepler/              

Add the JBoss Tools update site and search for FreeMarker

4. Basic example

Create a new Java project chosen com.vogella.freemarker.showtime. Create a new folder chosen lib and add the Freemarker library to it. Add this library to the classpath for your project.

If you don't know how to accomplish that, please run into the Eclipse IDE Tutorial for instructions on the required steps.

Create a new folder chosen templates within the binder of the com.vogella.freemarker.commencement package. Inside that, create the following file with name helloworld.ftl.

                <html> <head>   <title>${title} </head> <body>   <h1>${title}</h1>    <p>${exampleObject.proper name} by ${exampleObject.developer}</p>    <ul>     <#list systems equally system>       <li>${system_index + 1}. ${organisation.proper name} from ${system.programmer}</li>     </#list>   </ul>  </torso> </html>              

Create the following class which demonstrates the usage of Java objects in templates.

                                  bundle                  com.vogella.freemarker.first                  ;                  public                  class                  ValueExampleObject                  {                  private                  String                  proper name                  ;                  private                  Cord                  developer                  ;                  public                  ValueExampleObject                  (                  String                  name                  ,                  String                  programmer                  )                  {                  this                  .                  proper name                  =                  name                  ;                  this                  .                  developer                  =                  developer                  ;                  }                  public                  String                  getName                  ()                  {                  return                  proper noun                  ;                  }                  public                  String                  getDeveloper                  ()                  {                  render                  developer                  ;                  }                  }                              

Create the following class which creates the input for this template and creates the output.

                                  package                  com.vogella.freemarker.first                  ;                  import                  coffee.io.File                  ;                  import                  java.io.FileWriter                  ;                  import                  java.io.OutputStreamWriter                  ;                  import                  coffee.io.Writer                  ;                  import                  java.util.ArrayList                  ;                  import                  java.util.HashMap                  ;                  import                  java.util.List                  ;                  import                  java.util.Locale                  ;                  import                  java.util.Map                  ;                  import                  freemarker.template.Configuration                  ;                  import                  freemarker.template.Template                  ;                  import                  freemarker.template.TemplateExceptionHandler                  ;                  import                  freemarker.template.Version                  ;                  public                  class                  MainTest                  {                  public                  static                  void                  master                  (                  String                  []                  args                  )                  throws                  Exception                  {                  // 1. Configure FreeMarker                  //                  // You should practise this ONLY ONCE, when your awarding starts,                  // and so reuse the same Configuration object elsewhere.                  Configuration                  cfg                  =                  new                  Configuration                  ();                  // Where do we load the templates from:                  cfg                  .                  setClassForTemplateLoading                  (                  MainTest                  .                  course                  ,                  "templates"                  );                  // Some other recommended settings:                  cfg                  .                  setIncompatibleImprovements                  (                  new                  Version                  (                  2                  ,                  3                  ,                  20                  ));                  cfg                  .                  setDefaultEncoding                  (                  "UTF-8"                  );                  cfg                  .                  setLocale                  (                  Locale                  .                  US                  );                  cfg                  .                  setTemplateExceptionHandler                  (                  TemplateExceptionHandler                  .                  RETHROW_HANDLER                  );                  // 2. Proccess template(s)                  //                  // You lot will do this for several times in typical applications.                  // two.1. Prepare the template input:                  Map                  <                  String                  ,                  Object                  >                  input                  =                  new                  HashMap                  <                  String                  ,                  Object                  >();                  input                  .                  put                  (                  "title"                  ,                  "Vogella example"                  );                  input                  .                  put                  (                  "exampleObject"                  ,                  new                  ValueExampleObject                  (                  "Java object"                  ,                  "me"                  ));                  List                  <                  ValueExampleObject                  >                  systems                  =                  new                  ArrayList                  <                  ValueExampleObject                  >();                  systems                  .                  add                  (                  new                  ValueExampleObject                  (                  "Android"                  ,                  "Google"                  ));                  systems                  .                  add                  (                  new                  ValueExampleObject                  (                  "iOS States"                  ,                  "Apple"                  ));                  systems                  .                  add                  (                  new                  ValueExampleObject                  (                  "Ubuntu"                  ,                  "Approved"                  ));                  systems                  .                  add together                  (                  new                  ValueExampleObject                  (                  "Windows7"                  ,                  "Microsoft"                  ));                  input                  .                  put                  (                  "systems"                  ,                  systems                  );                  // 2.two. Get the template                  Template                  template                  =                  cfg                  .                  getTemplate                  (                  "helloworld.ftl"                  );                  // 2.3. Generate the output                  // Write output to the panel                  Writer                  consoleWriter                  =                  new                  OutputStreamWriter                  (                  Arrangement                  .                  out                  );                  template                  .                  process                  (                  input                  ,                  consoleWriter                  );                  // For the sake of example, likewise write output into a file:                  Writer                  fileWriter                  =                  new                  FileWriter                  (                  new                  File                  (                  "output.html"                  ));                  endeavour                  {                  template                  .                  procedure                  (                  input                  ,                  fileWriter                  );                  }                  finally                  {                  fileWriter                  .                  close                  ();                  }                  }                  }                              

five. Useful FTL tricks

5.1. Reuse common template fragments

When you find yourself copy-pasting mutual parts betwixt templates a lot, you should probably use macros.

Continuing our terminal example, create a new binder called lib inside the templates directory, and there create a file chosen utils.ftl, with this content:

                  <#macro page>   <html>   <head>     <title>${title}   </caput>   <body>     <h1>${title}</h1>      <#-- This processes the enclosed content:  -->     <#nested>   </body>   </html> </#macro>  <#macro otherExample p1 p2>   <p>The parameters were: ${p1}, ${p2}</p> </#macro>                

Now you can simplify helloworld.ftl like this:

                  <#import "lib/utils.ftl" as u>  <@u.page>   <p>${exampleObject.name} by ${exampleObject.developer}</p>    <ul>     <#listing systems as system>       <li>${system_index + 1}. ${system.proper noun} from ${system.developer}</li>     </#list>   </ul>    <#-- Just some other example of using a macro: -->   <@u.otherExample p1=11 p2=22 /> </@u.folio>                

Another manner of reusing template fragments is moving the mutual fragment into its own ftl file. Then just insert it with <#include "lib/myfragment.ftl">. This is less flexible than macros, but simpler in concept: it mimics copy-pasting.

5.2. Variables

You tin can define and assign content to variables inside the FTL files for easy reuse.

                  <#assign var_link = "https://www.vogella.com/people/larsvogel.html">  <a href="${var_link}">About Lars Vogel</a>                

5.3. If then else

` You can handle if / else cases, see below for an example.

                  <#assign name = "${article.getName()}">   <#if name?starts_with("https")>     <a href="http://www.larn.com</a>     <#else>     <a href="http://www.vogella.com/tutorials/${name}/article.html">${championship}</a> </#if>                

v.4. Treatment null/undefined values

FreeMarker requires you to provide an explicit default for variables, so avoid values that are nada or undefined:

                  <!-- Acts like if the color was N/A if there'south no color: --> <p>Color: ${color!'Due north/A'}</p>  <!-- Avoid the whole color row if in that location's no color: --> <#if colour??>   <p>Color: ${color}</p> </#if>                

5.5. Escape

When generating HTML, information technology'due south important to escape <, &, etc. in values that were not meant to store HTML and tin can incorporate these problematic characters. You lot can apply such escaping like ${message?html}. You can also ask FreeMarker to add ?html to all ${} -s in a section similar this:

                  <#escape 10 as x?html>   <p>Sender: ${from}   <p>Title: ${title}   <p>Message: ${body} </#escape>                

It's important to understand that #escape just affects the ${} bits that are inside the enclosed section in the template file when you look at it in a text editor. That means, ${} embracements which are in other templates or macros called from at that place, won't exist afflicted.