Saturday, February 22, 2014

FreeMarker Introduction

FreeMarker is a template engine that helps to generate text based on templates. Examples, generation of dynamic web pages, source code generators etc. Freemarker helps to separate the application logic and page design. FreeMarker is a Java library and is free to use with the BSD license terms.

FreeMarker supports a powerful template language which helps to bind a data-model and template together to produce the output.

Data Model 

All the data that the template can use/ refer is packed into a data-model. From the perspective of the template the data-model is a tree structure holding data. The data model tree can contain scalars that store a single value, containers that store other variables or sequences that store other variables in an ordered sequence.

Template

Templates use FTL tags (Freemarker Template Language) tags that provide instructions to FreeMarker. All the Freemarker tags start with #. 

FreeMarker Download

To use the examples below download Freemarker from http://freemarker.org/ and include the freemarker.jar in the application CLASSPATH. There are no other dependencies.

Freemarker Example

This example is an introduction to get quickly started with FreeMarker and understand the basic usage principles. Let's say we are interested in reporting a list of books (preferably in database) as a HTML table.

Data Model Example

First step is to create the data model. For simplicity we have ignored reading the actual data from database but instead fill our data model with some static data. Here we create a data model with a list of books and a scalar variable with report generated date interpreted as string.

// Create a data-model      
Map<String, Object> root = new HashMap<String, Object>();
List<Object> bookList = new LinkedList<Object>();
bookList.add(new Book("Gambardella, Matthew", "XML Developer's Guide"));
bookList.add(new Book("Ralls, Kim", "Midnight Rain"));
bookList.add(new Book("Corets, Eva", "Maeve Ascendant"));
root.put("bookList", bookList);

Date now = new Date();
root.put("ReportDate", now.toString());

For reference here is the Book class we use.

package com.sourcetricks.freemarker;

public class Book {

    private String author;
    private String title;
 
    public Book(String author, String title) {
       this.author = author;
       this.title = title;
    }
 
    public String getAuthor() {
       return author;
    }
 
    public String getTitle() {
      return title;
    }
}

Template Example

In this template we use FTL tags to bind data in our model to the HTML page. We use <#if> to check if books are present and <#list> to parse the book list. 

<!DOCTYPE html>
<html>
<head>
  <title>Welcome!</title>
</head>
<body>
  <#if bookList??>
     <p>No of books = ${bookList?size}</p>
     <table border="1">
       <tr>
         <th>Author</th>
         <th>Title</th>
       </tr>
       <#list bookList as book>
       <tr>
         <td>${book.author}</td>
         <td>${book.title}</td>
       </tr>
       </#list>
      </table>
   <#else>
       No books found
   </#if>
   <p>Reported at: ${ReportDate}</p>
</body>
</html>  

Main Program

Here is our main program which binds the data model and the template together and produces the required HTML page output.

package com.sourcetricks.freemarker;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import freemarker.template.Version;

public class FreemarkerTest {

  public static void main (String[] args) {
  
    // Create and adjust the configuration. Needed once for the application.
    Configuration cfg = new Configuration();

    try {
      cfg.setDirectoryForTemplateLoading(new File("resources"));
    } catch (IOException e) {
      e.printStackTrace();
    }
    
    cfg.setObjectWrapper(new DefaultObjectWrapper());
    cfg.setDefaultEncoding("UTF-8");
    cfg.setTemplateExceptionHandler(TemplateExceptionHandler.HTML_DEBUG_HANDLER);
    cfg.setIncompatibleImprovements(new Version(2, 3, 20));
    
    // Create a data-model      
    Map<String, Object> root = new HashMap<String, Object>();
    List<Object> bookList = new LinkedList<Object>();
    bookList.add(new Book("Gambardella, Matthew", "XML Developer's Guide"));
    bookList.add(new Book("Ralls, Kim", "Midnight Rain"));
    bookList.add(new Book("Corets, Eva", "Maeve Ascendant"));
    root.put("bookList", bookList);
    
    Date now = new Date();
    root.put("ReportDate", now.toString());
        
    try {
      // Get the template from the configured directory
      Template temp = cfg.getTemplate("test.ftl");
   
      // Process the template to merge data model 
      Writer out = new FileWriter("output.html");
      temp.process(root, out);
    } catch (IOException e) {
      e.printStackTrace();
    } catch (TemplateException e) {
      e.printStackTrace();
    }        
  }
}

Output



0 comments :

Post a Comment

Contact Form

Name

Email *

Message *

Back to Top