Text Templates in Mercury

Our first program will demonstrate how to use text templates in Java. We’ll use the Apache Velocity library, which offers similar functionality to Go’s text/template package.

First, add the Apache Velocity dependency to your project. If you’re using Maven, add this to your pom.xml:

<dependency>
    <groupId>org.apache.velocity</groupId>
    <artifactId>velocity-engine-core</artifactId>
    <version>2.3</version>
</dependency>

Now, let’s look at the Java code:

import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;

import java.io.StringWriter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

public class TextTemplates {
    public static void main(String[] args) {
        VelocityEngine ve = new VelocityEngine();
        ve.init();

        // We can create a new template and parse its body from a string.
        // Templates are a mix of static text and "references" enclosed in
        // ${...} that are used to dynamically insert content.
        String template1 = "Value is ${value}\n";
        
        // By using the VelocityEngine, we can evaluate the template with specific values.
        VelocityContext context = new VelocityContext();
        context.put("value", "some text");
        StringWriter writer = new StringWriter();
        ve.evaluate(context, writer, "t1", template1);
        System.out.print(writer.toString());

        context.put("value", 5);
        writer = new StringWriter();
        ve.evaluate(context, writer, "t1", template1);
        System.out.print(writer.toString());

        context.put("value", Arrays.asList("Java", "Kotlin", "Scala", "Groovy"));
        writer = new StringWriter();
        ve.evaluate(context, writer, "t1", template1);
        System.out.print(writer.toString());

        // If the data is an object we can use the ${object.field} syntax to access its fields.
        String template2 = "Name: ${person.name}\n";
        
        Person person = new Person("Jane Doe");
        context.put("person", person);
        writer = new StringWriter();
        ve.evaluate(context, writer, "t2", template2);
        System.out.print(writer.toString());

        // The same applies to maps.
        Map<String, String> map = new HashMap<>();
        map.put("name", "Mickey Mouse");
        context.put("person", map);
        writer = new StringWriter();
        ve.evaluate(context, writer, "t2", template2);
        System.out.print(writer.toString());

        // Velocity provides #if/#else directives for conditional execution.
        String template3 = "#if($value)yes#else no#end\n";
        
        context.put("value", "not empty");
        writer = new StringWriter();
        ve.evaluate(context, writer, "t3", template3);
        System.out.print(writer.toString());

        context.put("value", "");
        writer = new StringWriter();
        ve.evaluate(context, writer, "t3", template3);
        System.out.print(writer.toString());

        // #foreach directive lets us loop through collections.
        String template4 = "Range: #foreach($item in $list)$item #end\n";
        
        context.put("list", Arrays.asList("Java", "Kotlin", "Scala", "Groovy"));
        writer = new StringWriter();
        ve.evaluate(context, writer, "t4", template4);
        System.out.print(writer.toString());
    }

    static class Person {
        private String name;

        Person(String name) {
            this.name = name;
        }

        public String getName() {
            return name;
        }
    }
}

To run the program, compile and execute the Java file:

$ javac -cp .:velocity-engine-core-2.3.jar TextTemplates.java
$ java -cp .:velocity-engine-core-2.3.jar TextTemplates
Value is some text
Value is 5
Value is [Java, Kotlin, Scala, Groovy]
Name: Jane Doe
Name: Mickey Mouse
yes
no
Range: Java Kotlin Scala Groovy 

This example demonstrates how to use Apache Velocity to create and execute text templates in Java. It covers basic variable substitution, object and map field access, conditional statements, and loops. While the syntax differs from Go’s text/template package, the core concepts remain similar.