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:
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.
Generated with BYOB.
License: CC-BY-SA.
This page is designed to last.
⇐ [This site is part of the UT webring] ⇒