Text Templates in Fortress

Our first program will demonstrate text templates in Java. We’ll use the Apache FreeMarker library, which is a popular templating engine for Java. Here’s the full source code:

import freemarker.template.*;
import java.io.*;
import java.util.*;

public class TextTemplates {
    public static void main(String[] args) throws Exception {
        // Create a configuration instance
        Configuration cfg = new Configuration(Configuration.VERSION_2_3_31);
        
        // Create a template from a string
        String templateContent = "Value is ${value}";
        Template t1 = new Template("t1", new StringReader(templateContent), cfg);
        
        // Create a data model
        Map<String, Object> data = new HashMap<>();
        data.put("value", "some text");
        
        // Process the template
        StringWriter out = new StringWriter();
        t1.process(data, out);
        System.out.println(out);
        
        // Process with different values
        data.put("value", 5);
        t1.process(data, new OutputStreamWriter(System.out));
        
        data.put("value", Arrays.asList("Java", "Kotlin", "Scala", "Groovy"));
        t1.process(data, new OutputStreamWriter(System.out));
        
        // Template for struct-like objects
        String template2Content = "Name: ${person.name}";
        Template t2 = new Template("t2", new StringReader(template2Content), cfg);
        
        Map<String, Object> person = new HashMap<>();
        person.put("name", "Jane Doe");
        data.put("person", person);
        t2.process(data, new OutputStreamWriter(System.out));
        
        // Conditional execution
        String template3Content = "<#if value?has_content>yes<#else>no</#if>";
        Template t3 = new Template("t3", new StringReader(template3Content), cfg);
        
        data.put("value", "not empty");
        t3.process(data, new OutputStreamWriter(System.out));
        System.out.println();
        
        data.put("value", "");
        t3.process(data, new OutputStreamWriter(System.out));
        System.out.println();
        
        // Looping through collections
        String template4Content = "Range: <#list languages as lang>${lang} </#list>";
        Template t4 = new Template("t4", new StringReader(template4Content), cfg);
        
        data.put("languages", Arrays.asList("Java", "Kotlin", "Scala", "Groovy"));
        t4.process(data, new OutputStreamWriter(System.out));
    }
}

To run this program, you’ll need to include the FreeMarker library in your classpath. You can download it from the FreeMarker website or use a dependency management tool like Maven or Gradle.

Let’s break down the main parts of this code:

  1. We start by creating a FreeMarker Configuration object, which is used to set up the template engine.

  2. We create templates using the Template class. The template syntax uses ${...} for variable interpolation, similar to the Go templates.

  3. We use a Map to represent the data model that will be used to populate the templates.

  4. The process method is used to execute the template with the given data model and write the output to a Writer.

  5. FreeMarker supports conditional statements using <#if>...<#else>...</#if> syntax.

  6. Looping through collections is done using the <#list>...</#list> syntax.

When you run this program, you should see output similar to the following:

Value is some text
Value is 5
Value is [Java, Kotlin, Scala, Groovy]
Name: Jane Doe
yes
no
Range: Java Kotlin Scala Groovy 

This example demonstrates how to use text templates in Java, including variable interpolation, conditional statements, and looping through collections. The FreeMarker library provides a powerful and flexible way to generate dynamic content in Java applications.