Of course! Let's dive into using FreeMarker with Python.

Executive Summary
While FreeMarker is a Java-based templating engine, it can be used in Python through a wrapper library called freemarker-python. This library allows you to use the familiar FreeMarker template syntax (.ftl files) directly within your Python applications.
What is FreeMarker?
FreeMarker is a "template engine," a tool for generating text output (like HTML, emails, XML, or configuration files) from templates and changing data.
Key Concepts:
- Template (
.ftlfile): A text file with special syntax for inserting dynamic data. - Data Model: A Python dictionary or object that holds the data you want to display in the template.
- Process: The engine takes the template and the data model, merges them, and produces the final output.
FreeMarker Syntax Example:

<h1>Welcome, ${user.name}!</h1>
<p>Your last login was on ${lastLogin?string('yyyy-MM-dd')}.</p>
<#if user.isAdmin>
<p>You have administrative privileges.</p>
</#if>
Setting Up Your Environment
First, you need to install the freemarker-python library. It's a pure Python implementation, so you don't need Java installed.
Installation:
pip install freemarker-python
A Simple "Hello, World!" Example
Let's start with the most basic example to see how the pieces fit together.
Step 1: Create the Template File
Create a file named hello.ftl in your project directory.

hello.ftl
Hello, ${name}!
Step 2: Write the Python Script
Create a Python script (e.g., main.py) in the same directory.
main.py
import freemarker
# 1. Create a configuration object
# This tells FreeMarker where to find your templates.
cfg = freemarker.Configuration(
version=freemarker.TemplateVersion(2_3_32), # Specify a FreeMarker version
update_missing_version=True,
)
# Set the directory where your templates are located
cfg.template_loader = freemarker.FileSystemLoader(search_dirs=["."])
# 2. Prepare your data (a Python dictionary)
data_model = {
"name": "Python User"
}
# 3. Load the template
template = cfg.get_template("hello.ftl")
# 4. Process the template with the data model
# The result is a string containing the merged output.
output = template.render(data_model)
# 5. Print the result
print(output)
To Run It:
python main.py
Expected Output:
Hello, Python User!
Advanced Features and Examples
FreeMarker is powerful because of its rich set of features. Let's explore some common ones.
Example 1: Loops and Conditionals
Template (user_list.ftl):
<h1>User List</h1>
<ul>
<#list users as user>
<li>
${user.name} (${user.email})
<#if user.isActive>
<span style="color: green;">(Active)</span>
<#else>
<span style="color: red;">(Inactive)</span>
</#if>
</li>
</#list>
</ul>
Python Script (generate_list.py):
import freemarker
cfg = freemarker.Configuration(version=freemarker.TemplateVersion(2_3_32))
cfg.template_loader = freemarker.FileSystemLoader(search_dirs=["."])
# Data model with a list of dictionaries
data_model = {
"users": [
{"name": "Alice", "email": "alice@example.com", "isActive": True},
{"name": "Bob", "email": "bob@example.com", "isActive": False},
{"name": "Charlie", "email": "charlie@example.com", "isActive": True},
]
}
template = cfg.get_template("user_list.ftl")
output = template.render(data_model)
print(output)
Expected Output:
<h1>User List</h1>
<ul>
<li>
Alice (alice@example.com)
<span style="color: green;">(Active)</span>
</li>
<li>
Bob (bob@example.com)
<span style="color: red;">(Inactive)</span>
</li>
<li>
Charlie (charlie@example.com)
<span style="color: green;">(Active)</span>
</li>
</ul>
Example 2: Using Built-in Functions (Transformations)
FreeMarker has many built-in functions for formatting data. They are accessed with the symbol.
Template (formatting.ftl):
<p>Raw price: ${price}</p>
<p>Formatted currency: ${price?string.currency}</p>
<p>Formatted number: ${price?string("0.00")}</p>
<p>Raw date: ${date}</p>
<p>Formatted date (short): ${date?string.short}</p>
<p>Formatted date (custom): ${date?string("yyyy-MM-dd HH:mm")}</p>
<p>Is the user an admin? ${user.isAdmin?string("Yes", "No")}</p>
Python Script (generate_formatted.py):
import freemarker
from datetime import datetime
cfg = freemarker.Configuration(version=freemarker.TemplateVersion(2_3_32))
cfg.template_loader = freemarker.FileSystemLoader(search_dirs=["."])
data_model = {
"price": 1234.567,
"date": datetime.now(),
"user": {"isAdmin": True}
}
template = cfg.get_template("formatting.ftl")
output = template.render(data_model)
print(output)
Note: The freemarker-python library is very good at converting Python types (like datetime) into their FreeMarker equivalents automatically.
Key Differences from Jinja2
If you're familiar with Python's popular Jinja2 library, here's how FreeMarker compares:
| Feature | FreeMarker (freemarker-python) |
Jinja2 |
|---|---|---|
| Language | Java-based, with a Python wrapper. | Native Python. |
| Syntax | ${var}, <#if>, <#list>, <#macro> |
{{ var }}, {% if %}, {% for %}, {% macro %} |
| Whitespace Control | More verbose, often requires <#ftl strip_whitespace> or manual trimming. |
Excellent built-in control ( and ). |
| Data Model | Expects data as a "data model" (dicts, objects). Very strict. | Works directly with Python objects and context variables. |
| Philosophy | Strict separation of logic and presentation. Logic is handled in the data model. | Allows some logic in templates (e.g., set, filter). |
| Use Case | Excellent for porting Java-based applications to Python. The de-facto standard for many Java systems. | The dominant templating engine in the Python web world (Flask, Django via extensions). |
When to Use FreeMarker in Python?
- Porting Java Apps: If you're migrating a Java application to Python, reusing existing
.ftltemplates is a huge win. - Cross-Language Projects: If your team uses both Java and Python, standardizing on FreeMarker for templating can be beneficial.
- Specific Requirements: If you are deeply familiar with FreeMarker's feature set or its advanced capabilities (like complex macro libraries) and need them in a Python context.
For most new Python projects, especially web applications, Jinja2 is often the more idiomatic and convenient choice. However, for the specific use cases above, freemarker-python is an excellent and robust tool.
