Thursday, March 24, 2016

Free Marker Template Engine With Object Data Model.

Template Engine is used when we separate our HTML coding from our source code. It is basically used when we try to follow MVC architecture in our code. Lots of  template engine available on market like Velocity,Freemarker,Rythm etc.

Here we try to focus on Freemarker template engine.

Template engines generates output with the help of template file and run time data.

 Template marker can use 2 different type of data model
  1. Object in Map model 
  2.  XML data in Map model
We need to follow the below steps to play with Freemarker template:

Step: 1
Download the latest stable Fremarker version from here.

Step: 2
Extract the downloaded folder and put the the jar in our project.

Step:3
Create Fremarker configuration object with version number and some recommend settings.
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setLocale(Locale.US);
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);


Step:4
Mentioning the template file location.
        cfg.setDirectoryForTemplateLoading(new File("./resources"));
        Template template = cfg.getTemplate("freemarker_template.ftl");


Step: 5 
Creating Data model part.

        List<SampleDataDTO> freemarkerListObjectData = new ArrayList<>();
        freemarkerListObjectData.add(new SampleDataDTO(1, "Test1", 28.2f, new BigDecimal("40000.00"), 5.2, 'm'));
        freemarkerListObjectData.add(new SampleDataDTO(2, "Test2", 29.2f, new BigDecimal("50000.00"), 6.2, 'f'));
       
        List<String> freemarkerListStringData = new ArrayList<>();
        freemarkerListStringData.add("1");
        freemarkerListStringData.add("2");
       
        Map<String, Object> freemarkerMapData = new HashMap();
        freemarkerMapData.put("mapdata1", "My First FreeMarker Page");
        freemarkerMapData.put("mapdata2", "UTF-8");
        freemarkerMapData.put("SampleDataDTO", freemarkerListObjectData);
        freemarkerMapData.put("SampleList", freemarkerListStringData);


Step: 6 
 Creating the output part.

  This is for console output:
        Writer consoleWriter = new OutputStreamWriter(System.out);
        template.process(freemarkerMapData, consoleWriter);


  This is for html output:     

        try (Writer fileWriter = new FileWriter(new File("output.html"))) {
            template.process(freemarkerMapData, fileWriter);
        }


Step: 7
Creating template file and save it with .ftl extention. Here it is a sample template file.


<#ftl strip_whitespace = true>

<#macro another_macro>
<#list SampleList as List>
    <li>${List_index + 1}. ${List}</li>
</#list>
</#macro>   


Complete code given below :

Main Class :

package freemarker;

import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
import java.io.File;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;

public class FreeMarker {

    public static void main(String[] args) throws TemplateException, IOException {
         /**
         * Create Fremarker configuration object with version number and some recommend settings.
         */

        Configuration cfg = new Configuration(Configuration.VERSION_2_3_23);
        cfg.setDefaultEncoding("UTF-8");
        cfg.setLocale(Locale.US);
        cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);


         
          /**
         * Mentioning the template file location.
         */

        cfg.setDirectoryForTemplateLoading(new File("./resources"));
        Template template = cfg.getTemplate("freemarker_template.ftl");
        

        /**
         * Creating Data model part.
         */

        List<SampleDataDTO> freemarkerListObjectData = new ArrayList<>();
        freemarkerListObjectData.add(new SampleDataDTO(1, "Test1", 28.2f, new BigDecimal("40000.00"), 5.2, 'm'));
        freemarkerListObjectData.add(new SampleDataDTO(2, "Test2", 29.2f, new BigDecimal("50000.00"), 6.2, 'f'));

       
        List<String> freemarkerListStringData = new ArrayList<>();
        freemarkerListStringData.add("1");
        freemarkerListStringData.add("2");
       
        Map<String, Object> freemarkerMapData = new HashMap();
        freemarkerMapData.put("mapdata1", "My First FreeMarker Page");
        freemarkerMapData.put("mapdata2", "UTF-8");
        freemarkerMapData.put("SampleDataDTO", freemarkerListObjectData);
        freemarkerMapData.put("SampleList", freemarkerListStringData);
        

        /**
         * Creating the output part.
         */

        Writer consoleWriter = new OutputStreamWriter(System.out);
        template.process(freemarkerMapData, consoleWriter);

       
        /**
         * For the sake of example, also write output into a file.
         */

        try (Writer fileWriter = new FileWriter(new File("output.html"))) {
            template.process(freemarkerMapData, fileWriter);
        }
    }
}


DTO or Bean Class 

package freemarker;

import java.math.BigDecimal;


public class SampleDataDTO {
    private int id ;
    private String name;
    private float age;
    private BigDecimal salary;
    private double exp;
    private char sex;

    public SampleDataDTO() {
    }
   
    public SampleDataDTO(int id, String name, float age, BigDecimal salary, double exp, char sex) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.exp = exp;
        this.sex = sex;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public float getAge() {
        return age;
    }

    public BigDecimal getSalary() {
        return salary;
    }

    public double getExp() {
        return exp;
    }

    public char getSex() {
        return sex;
    }


.ftl files :

 Main Ftl File:

<#ftl strip_whitespace = true>
<#-- Main template file starts-->
<#-- Importing Other template file-->

<#import "sub_freemarker_template.ftl" as sub_template>
<#import "another_freemarker_template.ftl" as another_template>
<#-- Creating variable.-->
<#assign myVar>This is my variable</#assign>
<!DOCTYPE html>
<html>
    <#-- Calling Macro-->
    <@sub_template.head>
     </@sub_template.head>
    <body>
        <#-- Checking if condition and print variable.-->
        <#if myVar == "This is my variable">
            <div>${myVar}</div>
        <#elseif myVar == "">
            <div>blank</div>
        <#else>
            <div>blank</div>
        </#if>
        <#-- Using Macro.-->
        <@another_template.another_macro> 
        <#-- Showing data from  datamodel. Here it is simple key from Map-->  
        <div>${mapdata1}</div>
        <div>${mapdata2}</div>
        </@another_template.another_macro> 
            <ul>

        <#-- Showing data from  datamodel. Here it is List Object from Map-->   
                 <#list SampleDataDTO as Sample>
                    <li>${Sample_index + 1}. ${Sample.name} from ${Sample.age}</li>
                </#list>
            </ul>
        </body>
    </html>


Macro Ftl
<#ftl strip_whitespace = true>
<#macro head>
<#assign charset="UTF-8">
<#assign title="Example">
<#assign content>This is content</#assign>
    <head>
        <title>${title}</title>
        <meta charset="${charset}">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
</#macro>


Macro Ftl
 
<#ftl strip_whitespace = true>

<#macro another_macro>
<#list SampleList as List>
    <li>${List_index + 1}. ${List}</li>
</#list>
</#macro>     

 

No comments:

Post a Comment