librelist archives

« back to archive

Configure jinja2

Configure jinja2

From:
Ralf Jung
Date:
2012-05-08 @ 20:29
Hi list,

what is the recommended way to configure the jinja2 set up by Flask? 
Specifically, I'd like to change the undefined class to jinja2.StrictUndefined 
and add some filters. Currently this looks like this:

import jinja2, util
assert app.jinja_env.undefined == jinja2.Undefined
app.jinja_env.undefined = jinja2.StrictUndefined
app.jinja_env.filters['datum'] = util.datum
app.jinja_env.filters['js'] = util.javaScriptLiteral

However, especially the first part feels rather hacky since the "undefined" 
member of jinja2 is undocumented and I got it from the source code. I found no 
easy way to access the arguments passed to the environment constructor in the 
flask app, since the dict is immutable.
Any hint would be appreciated.

Kind regards,
Ralf

Re: [flask] Configure jinja2

From:
Simon Sapin
Date:
2012-05-08 @ 20:46
Le 08/05/2012 22:29, Ralf Jung a écrit :
> Hi list,
>
> what is the recommended way to configure the jinja2 set up by Flask?
> Specifically, I'd like to change the undefined class to jinja2.StrictUndefined
> and add some filters. Currently this looks like this:
>
> import jinja2, util
> assert app.jinja_env.undefined == jinja2.Undefined
> app.jinja_env.undefined = jinja2.StrictUndefined
> app.jinja_env.filters['datum'] = util.datum
> app.jinja_env.filters['js'] = util.javaScriptLiteral
>
> However, especially the first part feels rather hacky since the "undefined"
> member of jinja2 is undocumented and I got it from the source code. I found no
> easy way to access the arguments passed to the environment constructor in the
> flask app, since the dict is immutable.
> Any hint would be appreciated.

Hi,

"jinja_env.filters['foo'] = bar" is a documented API in Jinja, although 
Flask has a shortcut for that with app.add_template_filter and 
@app.template_filter.

The jinja_options dict is immutable as it is a class attribute, shared 
by all instances. If you want, you can inherit from the Flask class to 
override it. Something like this:

class MyFlask(Flask):
     jinja_options = dict(Flask.jinja_options, foo=bar)


However, all parameters of jinja2.Environment correspond to attributes 
with the same names. It is my understanding that the attributes are 
public API too, although the docs are unclear. They do say: "Instances 
of this class may be modified if they are not shared and if no template 
was loaded so far."

So in my opinion "app.jinja_env.undefined = jinja2.StrictUndefined" is 
fine, as long as it is before any template is loaded.

Regards,
-- 
Simon Sapin

Re: [flask] Configure jinja2

From:
Ralf Jung
Date:
2012-05-09 @ 08:15
Hi,

> The jinja_options dict is immutable as it is a class attribute, shared
> by all instances. If you want, you can inherit from the Flask class to
> override it. Something like this:
> 
> class MyFlask(Flask):
>      jinja_options = dict(Flask.jinja_options, foo=bar)
Ah, this is the way that's supposed to be done... I thought I had to override 
this create_jinja_environment function.

> However, all parameters of jinja2.Environment correspond to attributes
> with the same names. It is my understanding that the attributes are
> public API too, although the docs are unclear. They do say: "Instances
> of this class may be modified if they are not shared and if no template
> was loaded so far."
> 
> So in my opinion "app.jinja_env.undefined = jinja2.StrictUndefined" is
> fine, as long as it is before any template is loaded.
I was not sure this the attribute is not mentioned again in the list of 
properties of an environment - but on the other hand, the name does not start 
with a _ either. So I guess I'll just keep it, thanks to the assert I am 
pretty sure I will notice any interface changes.

Thanks for your quick reply!
Kind regards,
Ralf

Re: [flask] Configure jinja2

From:
Simon Sapin
Date:
2012-05-09 @ 08:25
Le 09/05/2012 10:15, Ralf Jung a écrit :
> Ah, this is the way that's supposed to be done... I thought I had to override
> this create_jinja_environment function.

Of course, you can do that too. Whatever is more convenient for you.