Getting Mako To Look For Templates Outside An App
A few weeks back, as I was writing the new SaWALi (as a Pylons application this time, instead of being an independent framework), I faced the problem of getting the Mako template engine to look for files outside of the application directory. This is important for me because I want SaWALi to be `reusable`, meaning I don't want to make a copy of SaWALi for each website that I'll be making/maintaining.
The answer came to me when I came across another developer's blog (I don't remember where) post that spoke of using the BaseController's __before__ method. The post was, if I remember correctly, about user authentication— which taught me how to implement SaWALi's own user authentication, and I'm really sorry I can't remember which blog it is and I can credit it— but what the heck, right? If it can authenticate users, it can do other things.
So what I did was, first: I created a key in my .ini file whose value is the absolute path to my "external templates", like:
sawali.templates = /home/user/not_my_application_directory/templates
I don't think it needs to be an absolute path but for minimising potential headaches, I recommend do it just the same.
The second thing I did was tweak the BaseController of my application, which is in my_application/lib/base.py.
Since I defined my external templates path in my application's .ini file, pylons.config needs to be imported by base.py. Hence, I added the following in base.py:from pylons import config
Then I defined a __before__ method in BaseController, like so:
class BaseController(WSGIController):
def __before__(self):
templates = config.get("sawali.templates")
if templates:
config["pylons.app_globals"].mako_lookup.directories.insert(0, templates)
What happened? Well, we know that config["pylons.app_globals"].mako_lookup is an object that has a directories property, which is a list of paths. I simply inserted the path to my external templates so that Mako will know that it needs to check that path too when a controller returns a render("/some_template_file.html")
Nice, right? Anyway, I used insert instead of append because I want Mako to look in my external templates directory first. If you want Mako to check your application's template directory first, then simply append.