Document Templating Markup Language (DTML)
DocumentTemplate is a Python library implementing the Document Templating Markup Language (DTML), originally developed for the Zope application server. It allows for dynamic generation of HTML, XML, or other text documents using a tag-based templating system. The current version is 5.3, with releases typically tied to bug fixes or Python version compatibility updates.
Common errors
-
TypeError: 'HTML' object is not callable
cause Attempting to render a template by calling the instance directly (e.g., `template(context)`), which was the method in versions prior to 5.0.fixFor DocumentTemplate 5.0+, use the `render()` method: `template.render(**context)`. -
dtml-var: name '...' not found
cause The variable specified in a `dtml-var` tag (e.g., `name="my_var"`) does not exist in the context dictionary provided to the template.fixEnsure that your context dictionary includes a key matching the variable name. For nested access (e.g., `request.user.name`), verify all intermediate keys exist in the context. -
ValueError: Missing closing tag for dtml-if (or other dtml- block tag)
cause A block-level DTML tag, such as `dtml-if`, `dtml-in`, or `dtml-unless`, was opened but not properly closed with its corresponding `dtml-endif`, `dtml-endin`, or `dtml-endunless` tag.fixReview your template source to ensure all block-level DTML tags have their matching closing tags. Pay close attention to spelling and capitalization.
Warnings
- breaking The primary rendering method for templates changed from direct invocation (`template(**context)`) to an explicit `render()` method (`template.render(**context)`). Additionally, all arguments to `render`, `eval`, and `manage_edit` are now keyword-only.
- breaking Support for Python versions older than 3.10 was dropped. This includes Python 2.7, 3.5, 3.6, 3.7, 3.8, and 3.9.
- deprecated The `DT_` prefix for environment variables used to configure DocumentTemplate was removed. Environment variables are now expected without this prefix (e.g., `CACHE_SIZE` instead of `DT_CACHE_SIZE`).
- gotcha DTML syntax is unique and differs significantly from more modern templating languages like Jinja2, Django Templates, or Mako. It uses `dtml-` prefixed tags and a specific expression syntax, which can lead to confusion if familiar with other systems.
Install
-
pip install documenttemplate
Imports
- HTML
from DocumentTemplate.document import HTML
from DocumentTemplate import HTML
- DTMLFile
from DocumentTemplate import DTMLFile
Quickstart
from DocumentTemplate import HTML
import os
template_source = """
<h1>Hello <dtml-var name="user_name">!</h1>
<p>Your lucky number is <dtml-var name="lucky_number">.</p>
<dtml-if expr="lucky_number > 5">
<p>That's a big number!</p>
<dtml-else>
<p>That's a small number.</p>
</dtml-if>
<p>Using environment: <dtml-var expr="request.environ.get('TEST_ENV_VAR', 'N/A')"></p>
"""
# Prepare context dictionary
context = {
'user_name': 'Registry User',
'lucky_number': 7,
'request': {
'environ': {
'TEST_ENV_VAR': os.environ.get('TEST_ENV_VAR', 'DEFAULT_TEST_VALUE')
}
}
}
# Create template instance
template = HTML(template_source)
# Render the template
rendered_output = template.render(**context)
print(rendered_output)