replacing django's template engine with mako

29.07.2008

mako template engine is absolutely great. it is used by reddit, and python.org(of course there are lots of other sites like numaradanresme but probably these two are the most well known). it's as fast as cheetah(more flexible than cheetah) and faster than django's template engine. so why not replacing django template engine with mako? besides its syntax is beautiful than djte(well that's according to me).
django is one of the most well known web framework and the most popular python framework. so here's the instructions to bring these together.

first, download and install mako
$> sudo easy_install mako

and please be sure that it works properly.
$> python
>>> import mako
>>>

if you get importerror, there's no need to read further, return to step one.

we're ready to start a new project in django. start a new project and a new application, and open the settings.py file, we need to make settings.py file to become mako ready.
import os
PROJECT_ROOT = os.getcwd()
TEMPLATE_DIRS(
  os.path.join(PROJECT_ROOT, 'mako_templates')
)

#this tuple doesn't exist in settings.py file.
TEMPLATE_MODULES(
  os.path.join(PROJECT_ROOT, 'mako_modules')
)

pay attention to TEMPLATE_MODULES. why did we write this? answer is simple: to improve performance. by defining modules directory, mako caches the template file as a python module.
open the urls.py file and define the url routings. since this is a simple example (r'^$', 'myapp.views.index'), would be enough.
now open the views.py which is located on application dir.
from random import randint
from django.http import HttpResponse
from django.conf import settings
from mako.template import Template
from mako.lookup import TemplateLookup

template_dirs = getattr(settings, 'TEMPLATE_DIRS')
module_dirs = getattr(settings, 'TEMPLATE_MODULES')
default_mimetype=getattr(settings, 'DEFAULT_CONTENT_TYPE')

lookup_dirs = TemplateLookup(directories = template_dirs,
  module_directory = module_dirs)

def render_to_response(templatename, context={}, mimetype=default_mimetype):
  templates = lookup_dirs.get_template(templatename)
  renderer = template.render(**context)
  return HttpResponse(renderer, mimetype)

def rand(start=0, end=1000):
  return randint(start, end)

def index(request):
  rand_gen = rand()
  title = 'Yata'
  return render_to_response('index.html', locals())

we've setup our view successfully, now the fun part. we'll create our html files.
we won't create just a simple index.html file, instead we'll create base.html file first, then our index.html file will inherit base.html.
<html>
<head>
<title>${title}</title>
<meta http-equiv="content-type" content="application/xhtml+xml; charset=utf-8" />
</head>
<body>
${self.container()}
</body>
</html>

pay attention to ${self.container()}.
here's the index.html file.
<%inherit file="base.html" />
<%def name="container()">
${rand}
</%def>

as you notice container() is our def name, and in mako variables are defined with ${variable_name}.

that's all!
blog comments powered by Disqus