Introduction to Mako
Have you ever worked on a project in Python and thought to yourself, “Gee, it would be nice if I could dynamically generate web pages and/or text and have them directly interact with my program.” Well, you’re in luck because enter Mako templates. Mako is a template library and a Python Sever Page language, allowing content such as HTML, XML, and text to be integrated with Python. This idea of embedding Python in HTML for dynamic web pages is not a new concept, as in the past, Python Server Pages have been implemented by various server-side scripting engines. Although these days PSPs have been largely overshadowed by web development systems such as Django and Flask. Nonetheless, in a small scale project, or perhaps in a large one with a creative twist on using these templates, Mako provides a useful way to quickly and simply add templates to your project.
Installation
Installing Mako is quick and easy with pip.
pip install Mako
Usage
The simplest way to use Mako in your Python project is through the provided Template
class.
from mako.template import Template
tmp = Template("hello ${name}")
print(tmp.render(name="world!"))
We can also write out the templates using Mako’s syntax in a separate file and load it in.
from mako.template import Template
tmp = Template(filename='templates/home_page.html')
print(tmp.render())
Before moving on I’d like to quickly explain what’s going on in these two examples. The Template
object takes in a String or the location of the file containing the template. Either case, both contain the language used by Mako and is interpreted by the engine and is rendered using the render()
method.
Syntax
Expression Substitution
(1) ${headline} is a good news article for you.
(2) 2 to the power of 2 is ${pow(2,2)}.
# In the Python module
print(tmp.render(headline="News 24/7")) # Prints out (1)
Mako supports expression substitution. In the above example we have variable substitution (1), where we can supply the value in the render()
method as a keyword argument. Python renders whatever is in between the curly braces. Therefore, function calls (2) and other Python syntax is allowed.
Control Structures
% if credit:
credit to:
<ul>
% for c in credit:
<li> ${loop.index}: ${c}</li>
% endfor
</ul>
% endif
# Program
print(tmp.render(credit=["You", "Me", "Us", "Them"]))
Mako supports Python’s control structures such as: conditionals, loops, and try/except. In the avoid code we can see that basic structure for these structures. They all start with %
followed by a Python expression and are closed by a %
end<keyword> where keyword would be the same expression used. Note, variables accessible in the template can be used directly anywhere Python code is written (E.g. credit
in the if statement checks if the credit list exists) while variables in the Mako template language need to be accessed using ${}
. We can see here that an HTML file has its list dynamically grow by the credit list passed into the render
() method.
Tags
# A Python block whose variables can be accessed outside
<%
authors = " and ".join(str(x).upper() for x in byline)
author_column = "; authored by *{}*".format(authors)
%>
# Include: renders the file
<%include file="header.html"/>
# Def: defines a Python function that can be called
<%def name="add_exclaimation(s)">
${s}!!!!!!
</%def>
${add_exclaimation("hello")}
Lastly, Mako allows arbitrary Python code to be written in <% %>
tags, and there exists other tags such as the <%include/>
and <%def> </%def>
tags which allows other files to be rendered in the template and to define functions in the template itself respectively. I hope this introduction to Mako templates provided an insightful view into the usefulness of templates. Happy blogging!
References:
