I'm sorry for such long time without any reply, but I was investigating possible approaches of mixing Django and Jinja2 templates.
On Sunday, February 16, 2014 1:08:49 AM UTC+1, Russell Keith-Magee wrote: > > > On Sun, Feb 16, 2014 at 12:43 AM, Christopher Medrela <[email protected] > > wrote: > >> My last post was pretty long and the most important questions and >> statements >> have left unanswered, so I will repeat them. >> >> What I'm proposing now is more conservative proposal. Firstly, Django will >> support Jinja2 out-of-the-box, but DTL will remain the "blessed" option. >> > > As a broad statement, this sounds fine; but what does this mean in > practice? What does "out of the box" support look like? > The two main principles would be: 1) reusing existing interfaces and contracts 2) making switching from Djinja/jingo/django-jinja/coffin as easy as possible. Last month, Djinja and jingo were downloaded 650 times while coffin and django-jinja have each one 2k downloads. Coffin focus on imitating DTL. Therefore, the "out of box" support should be similar to django-jinja. Basically, the same functions will apply to Jinja2 as well as to Django templates. If you want to render a template, you write ``render_to_response(template_name)``, whether the template is Jinja2 or Django template. Templates will be distinguished by extension. How can it be achieved? - We need to move all existing functions (like `render_to_response`) from django.template to a new module. Let's call it `django.dtl`. - Then, we can create dummy implementations of `render_to_response` (and all other functions) that checks the template extension and dispatch to corresponding function from `django.dtl` or `jinja2`. - It would be nice to use the same loaders for both django.dtl and jinja2. This requires to rewrite existing Django loaders so that they fulfill the contract of `jinja2.Loader`. Secondly, Django will allow to mix DTL and Jinja2 templates (so you can >> include/inherit DTL template from Jinja2 one and vice versa). > > > Including doesn't sound like it would be any problem, but inheriting? Is > that really going to be possible? It seems to be possible. Consider parent Jinja2 template: Parent {% block overridden %}parent overridden block{% endblock %} {% block nonoverridden %}parent nonoverridden block{% endblock %} as well as child Jinja2 template: {% extends "parent.jinja2" %} {% block overridden %}child overridden block{% endblock %} Jinja2 compiles templates by generating valid Python code and passing it to `exec` function. The appropriate code for the former is: from __future__ import division from jinja2.runtime import LoopContext, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join, to_string, identity, TemplateNotFound name = 'parent' def root(context, environment=environment): if 0: yield None yield u'Parent ' for event in context.blocks['overridden'][0](context): yield event for event in context.blocks['nonoverridden'][0](context): yield event def block_nonoverridden(context, environment=environment): if 0: yield None yield u'parent nonoverridden block' def block_overridden(context, environment=environment): if 0: yield None yield u'parent overridden block' blocks = {'nonoverridden': block_nonoverridden, 'overridden': block_overridden} debug_info = '1=8' and for the child is: from __future__ import division from jinja2.runtime import LoopContext, TemplateReference, Macro, Markup, TemplateRuntimeError, missing, concat, escape, markup_join, unicode_join, to_string, identity, TemplateNotFound name = 'child' def root(context, environment=environment): parent_template = None if 0: yield None parent_template = environment.get_template('parent.jinja2', 'child') for name, parent_block in parent_template.blocks.iteritems(): context.blocks.setdefault(name, []).append(parent_block) for event in parent_template.root_render_func(context): yield event def block_overridden(context, environment=environment): if 0: yield None yield u'child overridden block' blocks = {'overridden': block_overridden} debug_info = '1=8' As you can see, child template loads parent template using `environment.get_template` method; then iterates over its blocks; finally delegates to it by calling `root_render_func` and passing the context. We can write Jinja2 loader that checks the template extension; if it's "jinja2", it delegates to another loader that is responsible for loading Jinja2 templates; otherwise, it loads appropriate Django template and wraps it with an adapter. The adapter must have the same interface as `jinja2.Template` -- probably only `blocks` and `root_render_func` need to be implemented. `root_render_func` will be similar to `Template.render` and `blocks` is a map from block names to functions rendering these blocks (these functions will be similar to `BlockNode.render`). We also need to tamper with `BlockNode.render` method in the case when the child template is DTL and the parent is written in Jinja2 so BlockNode can pass control to the block defined in parent template. As I see it, there are three possible options here: > 1) Add Jinja2 as a supported option, but stick with DTL as the default. > 2) Add Jinja2 as a supported option, and indicate that long term, we're > going to switch to Jinja as the default > 3) Add Jinja2 as a supported option and move to it immediately as the > default. > My personal preferences would be in that order. This is something where > historically, we would have gone to the BDFLs for a call; I suspect the > core team might need to have a quick discussion and make a call, lest this > turn into the mother of all bike sheds. First option is a necessary condition for the others and it seems to be big enough GSoC project, therefore I will focus on it. In the future, if we changed mind, we could move to other options. On Sunday, February 16, 2014 11:44:52 PM UTC+1, Donald Stufft wrote: > > On Feb 16, 2014, at 4:23 PM, Carl Meyer <[email protected]> wrote: > > >> 2) Jinja2 doesn't support 3.2. Will Django 1.8 support 3.2? > > > > Donald might be able to offer better hard numbers based on e.g. PyPI > > usage, but my impression is that usage of 3.2 is very low, and dropping > > it for 1.8 would not be a major problem. > > These numbers are about a month old, but > https://gist.github.com/dstufft/8455306 > Thank you very much, Donald! In short, the numbers are: 2.7 -- 6450k total downloads 3.2 -- 60k 3.3 -- 250k It seems like the support for Python 3.2 could be dropped. > -- You received this message because you are subscribed to the Google Groups "Django developers" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ae007cb9-5219-4a57-bb03-77f5ee58f1e1%40googlegroups.com. For more options, visit https://groups.google.com/groups/opt_out.
