views:

372

answers:

2

I'm using Pylons with Mako templates and I want to avoid typing this all the time:

${ h.some_function_that_outputs_html() | n }

I want to somehow mark the function, or a variable as safe (you can do that in Django) so I don't have to pipe-en all the time. Any ideas?

+3  A: 

According to the mako docs about filtering, you can set the default filters that are applied inside templates when creating a new Template as well as for the TemplateLookup (in which case this would apply by default for all the templates that it looks up), with the default_filters argument.

Pylons uses this argument with TemplateLookup to set the defaults for your project inside the config/environment.py file:

# Create the Mako TemplateLookup, with the default auto-escaping
config['pylons.app_globals'].mako_lookup = TemplateLookup(
    directories=paths['templates'],
    error_handler=handle_mako_error,
    module_directory=os.path.join(app_conf['cache_dir'], 'templates'),
    input_encoding='utf-8', default_filters=['escape'],
    imports=['from webhelpers.html import escape'])

This is why you get the escaping by default (which is not the case when you use Mako by yourself). So you could either change it globally in the config file, or not rely on the standard lookup. Beware that you should of course then explicitly use a filter to escape those things that do need escaping.

You can also pass a string "marked as safe" with the Pylons helper h.literal, for example if you would pass h.literal('This will <b>not</b> be escaped') to the template, say as a variable named spam, you could just use ${spam} without any escaping.

If you want the same effect when you call a certain function from inside a template, this function would need to return such a literal, or provide a helper for that function that calls h.literal on the result if you want to leave the original function alone. (or I guess you could also call it via a "Filtering def" (see same Mako doc as above), haven't experimented with that yet)

Steven
Thanks, this worked for me
Discodancer
Just a notice for people using the first solution (removing escape from default_filters) - you have to clear cache (rm -r data/templates/*) to see it working (I just spent some wondering what's wrong).
zefciu
+1  A: 

I just found out that if you put a html method in your class, then Mako will just call that method and output whatever it returns in the template.

So I did:

def __html__(self):
    return unicode(self)

That's basically what h.literal does.

Discodancer