StackStalk
  • Home
  • Java
    • Java Collection
    • Spring Boot Collection
  • Python
    • Python Collection
  • C++
    • C++ Collection
    • Progamming Problems
    • Algorithms
    • Data Structures
    • Design Patterns
  • General
    • Tips and Tricks

Friday, February 21, 2014

FreeMarker Introduction

 February 21, 2014     Java     No comments   

In this article, we will explore the concepts of Freemarker template engine and look at an example to use Freemarker to generate HTML output.

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

Email ThisBlogThis!Share to XShare to Facebook
Newer Post Older Post Home

0 comments:

Post a Comment

Follow @StackStalk
Get new posts by email:
Powered by follow.it

Popular Posts

  • Python FastAPI file upload and download
    In this article, we will look at an example of how to implement a file upload and download API in a Python FastAPI microservice. Example bel...
  • Avro Producer and Consumer with Python using Confluent Kafka
    In this article, we will understand Avro a popular data serialization format in streaming data applications and develop a simple Avro Produc...
  • Monitor Spring Boot App with Micrometer and Prometheus
    Modern distributed applications typically have multiple microservices working together. Ability to monitor and manage aspects like health, m...
  • Server-Sent Events with Spring WebFlux
    In this article we will review the concepts of server-sent events and work on an example using WebFlux. Before getting into this article it ...
  • Accessing the Kubernetes API
    In this article, we will explore the steps required to access the Kubernetes API and overcome common challenges. All operations and communic...
  • Python FastAPI microservice with Okta and OPA
    Authentication (AuthN) and Authorization (AuthZ) is a common challenge when developing microservices. In this article, we will explore how t...
  • Scheduling jobs in Python
    When developing applications and microservices we run into scenarios where there is a need to run scheduled tasks. Examples include performi...
  • Using Tekton to deploy KNative services
    Tekton is a popular open-source framework for building continuous delivery pipelines. Tekton provides a declarative way to define pipelines ...

Copyright © StackStalk