The mako template engine is a powerful module for Python used by many large sites including reddit.com. You simply push the variables you want into a context and then merge that with a text template.
Additionally, mako allows you to take advantage of the full power of the Python language and libraries by allowing calls to Python functions from inside the template.
In this article I’ll provide Python sample code for merging a set of key/value pairs in a properties file with a text template. A portion of the rendered output will come from a call to a Python function.
Prerequisites
I’m going to assume you have Python2 with pip installed. On Ubuntu, set the dependencies using:
sudo apt-get install python-dev python-pip pip install mako
Github project
The github project for this article contains several files:
- mako.template – the template that drives the ultimate rendering
- mako.properties – the values to be used in the template
- lincoln-quote.txt – external file to be inserted into rendering
- makoWithPythonFunction.py – merge properties and mako template
sudo apt-get install git git clone https://github.com/fabianlee/mako-python-function.git cd mako-python-function
The template
First, look at the template. You can see a simple variable substitution with ${var1} and ${who}. But even more interesting is the ${get_quote_and_indent()} which is the invocation of a Python function of the same name.
This is the first line, ${var1} ${get_quote_and_indent(person,"quote.txt",5)} ${who} This is the last line.
This function passes arguments using ‘person’ (a value from the properties file) as well as string and integer values.
Rendered output
When invoked, the property values are merged with the template and you can see that the ‘lincoln-quote.txt’ is output with indentation.
$ ./makoWithPythonFunction.py mako.template mako.properties This is the first line, this was in variable 1 Be sure you put your feet in the right place, then stand firm. Quote by lincoln This is the last line.
The code
Reading the properties file for values and creating the context for mako rendering is almost boilerplate, so I will only highlight here how the ‘get_quote_and_indent’ function is exposed for invocation in the template.
The Python function first needs to be defined of course, with the function name and arguments to be passed.
def get_quote_and_indent(author,basename,indent): ...
Then we need to expose the function for use by adding its key name and value along with all the other values loaded into our dictionary.
myprops['get_quote_and_indent'] = get_quote_and_indent
And then we pass this myprops dictionary to the mako Context, which is subsequently rendered.
ctx = Context(buf,**myprops) try: mytemplate.render_context(ctx)
REFERENCES
https://www.makotemplates.org/ (mako documentation)
https://github.com/pypa/pip/issues/5599#issuecomment-416318017 (pip broken on Ubuntu)
https://stackoverflow.com/questions/49964093/file-usr-bin-pip-line-9-in-module-from-pip-import-main-importerror-canno/49988228 (on uninstalling manually installed pip in favor of Ubuntu shipped pip)
NOTES
If pip broken on Ubuntu
sudo chown -R $USER:$USER ~/.cache python -m pip uninstall pip setuptools wheel sudo apt-get --reinstall install python-setuptools python-wheel python-pip