dataModel = new HashMap<>();
dataModel.put("reportTitle", "Quarterly Sales");
StringWriter out = new StringWriter();
Environment env = template.createProcessingEnvironment(dataModel, out);
// Configure environment settings before processing
env.setLocale(Locale.GERMANY);
env.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
env.setNumberFormat("#,##0.00");
env.setDateFormat("dd.MM.yyyy");
// Add variables directly to environment
env.setVariable("generatedAt", env.getObjectWrapper().wrap(new Date()));
// Process the template
env.process();
String result = out.toString();
// Access current environment from within custom directives/methods:
// Environment currentEnv = Environment.getCurrentEnvironment();
```
--------------------------------
### Test Simple Tag Loading from ClasspathTlds
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-javax-servlet/src/test/resources/freemarker/ext/jsp/webapps/tldDiscovery/WEB-INF/expected/test-noClasspath.txt
This snippet indicates the successful execution of simple tags when loaded from ClasspathTlds.
```Java
Executed TestSimpleTag2
Executed TestSimpleTag3
```
--------------------------------
### Simple Variable Assignment in FreeMarker
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/hashconcat.txt
Demonstrates basic variable assignment within a FreeMarker macro or template. Variables are assigned values using the '=' operator.
```ftl
a = 1
b = 2
c = 3
X = 4
---
1
2
3
4
```
```ftl
d = 10
e = 20
f = 30
X = 40
---
10
20
30
40
```
--------------------------------
### Generate FreeMarker API Documentation
Source: https://github.com/apache/freemarker/blob/2.3-gae/README.md
Generates the Javadoc for the FreeMarker API. The output is typically uploaded to the 'docs/api' directory of the website.
```bash
./gradlew javadoc
```
--------------------------------
### Capitalize Each Word in String
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/string-builtins1.txt
Converts the first letter of each word in a string to uppercase. Apply this for title-casing text.
```ftl
capitalize: Diebugsdie! * Vazzze 123456 --cdc-- --<<--@ X ${"kigyo"?upper_case}
```
--------------------------------
### Simple String Output
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/macros.txt
A basic FreeMarker template that outputs a static string. This is often used for simple text generation or as a base for more complex templates.
```ftl
Hello World! Today is Monday.
```
--------------------------------
### List with Else (Multiple Items)
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/list2.txt
Renders each item on a new line when there are multiple items. The 'Empty!' text is not shown as the list is not empty.
```ftl
aardvark
bear
cat
dog
```
--------------------------------
### String Interpolation and Escaping
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/string-builtins1.txt
Demonstrates string interpolation and how special characters are handled and escaped within strings, including Unicode and control characters.
```ftl
[a] = [a]
[a\'x'\nb] = [a\'x'\nb]
[\u0001\u001a ] = [\u0001\u001a ]
```
```ftl
[a] = [a]
[a\\'x\'\nb] = [a\\'x\'\nb]
[\x01\x1A ] = [\x01\x1A ]
[\x3C![CDATA[] = [\x3C![CDATA[]
[]]\x3E] = []]\x3E]
```
```ftl
[a] = [a]
[a\'x'\nb] = [a\'x'\nb]
[\u0001\u001A ] = [\u0001\u001A ]
[\n\r\t\f\b\"] = [\n\r\t\f\b\"]
[\/]= [\/]
[a/b] = [a/b]
[<\/script>] = [<\/script>]
[\u003C![CDATA[] = [\u003C![CDATA[]
[]]\u003E] = []]\u003E]
```
--------------------------------
### List with Items, Separator, and Else (Multiple Items)
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/list2.txt
Renders a comma-separated list within brackets. The 'Empty!' text is not shown as the list is not empty.
```ftl
[
aardvark,
bear,
cat,
dog
]
```
--------------------------------
### Hash Reassignment with List Test
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/hashliteral.txt
Shows reassigning a hash with a list and repeating the output. Observe how the list elements are accessed.
```ftl
<#assign test23 = {"a": "Hello, world!", "list": ["Temporary", "Temporary", "Temporary"]}>
${test23.a}
<#list test23.list as item>
${item}
#list>
${test23.c!1}
```
--------------------------------
### Test Simple Tag Execution with Multiple Iterations
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-javax-servlet/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/customTags1.txt
This test case demonstrates the execution of simple tags with multiple iterations. It shows how FreeMarker processes tags like 'simpletag1' and 'simpletag2', including their bodies and exit conditions.
```java
enter TestSimpleTag simpletag1
invoking body i=0
foo
enter TestSimpleTag simpletag2
invoking body i=0
bar
invoking body i=1
bar
invoking body i=2
bar
exit TestSimpleTag simpletag2
invoking body i=1
foo
enter TestSimpleTag simpletag2
invoking body i=0
bar
invoking body i=1
bar
invoking body i=2
bar
exit TestSimpleTag simpletag2
exit TestSimpleTag simpletag1
```
--------------------------------
### Expected Native Image Output
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-test-graalvm-native/README.md
This is the expected output when running the FreeMarker GraalVM native executable. It shows FreeMarker version and a simple HTML output generated by a template.
```txt
INFO: name : FreeMarker Native Demo, version : 2.3.35-nightly
Jan 15, 2025 4:28:19 PM freemarker.log._JULLoggerFactory$JULLogger info
INFO: result :
Hello : FreeMarker GraalVM Native Demo
Hello : FreeMarker GraalVM Native Demo
Test template for Apache FreeMarker GraalVM native support (2.3.35-nightly)
```
--------------------------------
### Numeric List with Items (Multiple Items)
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/list2.txt
Renders numbers enclosed in square brackets, with each number on a new line.
```ftl
[
11
22
33
]
```
--------------------------------
### Implement Custom Template Method (TemplateMethodModelEx)
Source: https://context7.com/apache/freemarker/llms.txt
Create custom functions callable from templates by implementing TemplateMethodModelEx. These functions receive arguments as TemplateModel objects. Ensure arguments are of the expected type to avoid runtime errors.
```java
import freemarker.template.*;
import java.util.List;
// Custom method to calculate total price
public class CalculateTotalMethod implements TemplateMethodModelEx {
@Override
public Object exec(List arguments) throws TemplateModelException {
if (arguments.isEmpty()) {
throw new TemplateModelException("calculateTotal requires a list argument");
}
TemplateModel arg = (TemplateModel) arguments.get(0);
if (!(arg instanceof TemplateSequenceModel)) {
throw new TemplateModelException("Argument must be a sequence");
}
TemplateSequenceModel products = (TemplateSequenceModel) arg;
double total = 0;
for (int i = 0; i < products.size(); i++) {
TemplateHashModel product = (TemplateHashModel) products.get(i);
TemplateNumberModel price = (TemplateNumberModel) product.get("price");
if (price != null) {
total += price.getAsNumber().doubleValue();
}
}
return total;
}
}
// Register with configuration
cfg.setSharedVariable("calculateTotal", new CalculateTotalMethod());
// Usage in template:
// Total: $${calculateTotal(products)?string("0.00")}
// Output: Total: $5.27
```
--------------------------------
### Java Collections in FreeMarker
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-javax-servlet/src/test/resources/freemarker/ext/jsp/webapps/basic/WEB-INF/expected/attributes-2.3.0.txt
Shows how different Java collection types are interpreted and represented when used within a FreeMarker template context. Note that 'MyMap' is ignored.
```ftl
Values created in Java:
LinkedList: [1, 2, 3] [freemarker.template.SimpleSequence]
ArrayList: [1, 2, 3] [freemarker.template.SimpleSequence]
MyList: [1, 2, 3] [freemarker.template.SimpleSequence]
LinkedHashMap: {a=1, b=2, c=3} [freemarker.template.SimpleHash]
TreeMap: {a=1, b=2, c=3} [freemarker.template.SimpleHash]
MyMap: [IGNORED] [freemarker.template.SimpleHash]
TreeSet: [1, 2, 3] [freemarker.template.SimpleSequence]
```
--------------------------------
### Numeric List with Items, Separator, and Else (Multiple Items)
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/list2.txt
Renders a comma-separated list of numbers within brackets. The 'Empty!' text is not shown.
```ftl
[
11,
22,
33
]
```
--------------------------------
### XML Processing with Namespaces and CDATA
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/xml.txt
Illustrates how to handle XML elements with namespaces and CDATA sections in FreeMarker. Pay attention to how CDATA content is preserved, including special characters.
```ftl
text1text2
```
```ftl
text1
```
--------------------------------
### Assigning Variables and Using Macros in FreeMarker
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/include.txt
Assigns values to variables and defines a macro for repeated content inclusion. This snippet demonstrates basic variable assignment and macro definition within a FreeMarker template.
```ftl
<#assign foo="assigning from included template", bar=" Can you see me? ">
<#macro twice><#nested/>${bar}<#nested/>#macro>
<#include "nestedinclude.ftl">
```
--------------------------------
### Hash Concatenation Test
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/hashliteral.txt
Shows how to concatenate two hashes to create a new hash with combined key-value pairs.
```ftl
<#assign hash1 = { "a": 1, "b": 2 }>
<#assign hash2 = { "b": 3, "c": 4 }>
<#assign combined = hash1 + hash2>
<#list combined?keys as k>
${k} => ${combined[k]}
#list>
```
--------------------------------
### List with Separator (Multiple Items)
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/list2.txt
Renders a comma-separated list when there are multiple items. Use this for simple list outputs.
```ftl
aardvark,
bear,
cat,
dog
```
--------------------------------
### Numeric List with Else (Multiple Items)
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/list2.txt
Renders each number on a new line when there are multiple items. The 'Empty!' text is not shown.
```ftl
11
22
33
```
--------------------------------
### Catch-All Macro Parameter Test
Source: https://github.com/apache/freemarker/blob/2.3-gae/freemarker-jython25/src/test/resources/freemarker/test/templatesuite/expected/macros.txt
Tests the behavior of a macro with a catch-all parameter. This allows the macro to accept a variable number of arguments, which are then collected into a list.
```ftl
foo=a baz=[]
foo=a baz=[bar=b]
foo=a baz=[bar=b, baz=c]
```
--------------------------------
### FreeMarker Template Language (FTL) Basics
Source: https://context7.com/apache/freemarker/llms.txt
Basic FTL syntax for interpolations, directives, conditionals, loops, default values, null-safe access, and built-in functions. The .ftlh extension enables HTML auto-escaping.
```ftl
<#-- welcome.ftlh - Template with auto-escaping -->
Welcome, ${user}!
${message}
<#-- Conditional logic -->
<#if products?has_content>
<#-- List iteration -->
<#list products as product>
- ${product.name} - $${product.price}
#list>
<#else>
No products available.
#if>
<#-- Default values for missing variables -->
Email: ${email!"Not provided"}
<#-- Null-safe access -->
City: ${user.address.city!"Unknown"}
<#-- Built-in functions -->
Total products: ${products?size}
User uppercase: ${user?upper_case}
Today: ${.now?string("yyyy-MM-dd")}
```