Sneaking Metadata into Mako Templates

Monday, January 05, 2026

Here’s a little trick I use to sneak some metadata into my Mako templates.

You can define python methods as top-level definitions in a Mako template. Then, from the python side, you access the module that implements the template, and simply call the function directly.

Here’s an example:

#!/usr/bin/env -S uv run --script
# /// script
# requires-python = ">=3.12"
# dependencies = [
#   "mako",
# ]
# ///

from mako.template import Template

# Construct the template, containing `foo` as a top-level module definition.
template = Template("""
<%!
def foo():
    return { "extension": ".html" };
%>

<h1>Hello world!</h1>
""")
# Access the module of the template, call `foo` directly.
print(template.module.foo())
# Let's render the template as well while we're at it.
print(template.render())

To test this, you can either install Mako locally, or you can run the script with uv, which handles the dependencies implicitly. Serhii wrote a concise blogpost explaining this functionality.

Executing the script prints the following:

❯ uv run --script test.py
{'extension': '.html'}



<h1>Hello world!</h1>

In the documentation of the Template class this module field is mentioned implicitly, so I’m not sure if this is supposed to be a stable feature of the Mako API. For my personal website this is fine.

While this is a powerful mechanism, I only use it to annotate my templates with metadata (for now). E.g. what the output extension of the file produced by the template should be, or if the template is supposed to be reusable or produces one particular page, etc.

Because Mako is so flexible, I don’t just use it for templating-specific stuff, but also as a way to do poor man’s literate programming in Python. While it’s a bit messy, it’s also effective and gets the job done.


View as: md (raw), txt.


Generated with BYOB. License: CC-BY-SA. This page is designed to last.

[This site is part of the UT webring]