Opened 10 years ago

Closed 10 years ago

#23591 closed Uncategorized (needsinfo)

RFC: Shared parser-level context to all templates involved in output

Reported by: Anton Stoychev Owned by: nobody
Component: Template system Version: 1.7
Severity: Normal Keywords: template, parser, output, context
Cc: Aymeric Augustin Triage Stage: Unreviewed
Has patch: no Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

I've spend a few days thinking of a better way to defined assets (css and javascripts) in templates and partials. This is what I came across and what I came up with.

Problem

Django templates have the ability to extend and include other templates. So a full HTML (or other format) output can consist of rendering several templates, which could have been extended or included.

However, each template is rendered separately and is not aware that in the current output there would be other templates involved.

In the case of extended templates the only thing shared is the rendering context (variables, etc) but still there isn’t awareness that other templates are also rendered to make the complete output.

Now, this “awareness” sounds like we should sacrifice encapsulation, but there is a solution which in fact improves encapsulation.

Don’t think this is aiming “all templates must share context with variables and other info”. It’s not about this. We must, however, enable templates to say “hey, i need this and this, and i’m rendering that and that, account for me”. This improves encapsulation.

Common scenario

You are outputting HTML. You have a base template like layout.html and other templates like home.html. The template home.html also includes _nav.html and _footer.html.

Now, _footer.html and _nav.html have some cool animations going on. So they need certain CSS and JavaScript files. Right now in Django, you can’t defined these in the _footer.html and _nav.html and be outputted in the end of layout.html because included templates neither share context, nor can influence block tags.

So you end up defining the required CSS and JavaScript for the partials in either home.html or layout.html. This way you already make home.html and layout.html aware of the partials and if partials change, home.html and layout.html should also change. That is not good encapuslation.

Proposed Solution

Django templates are rendered on 2 levels:

  • parser level rendering (compile template to DOM-like structure)
  • context level rendering (with context and variables)

We aim better encapsulation so let limit ourselves to parser level. This is the lower level rendering where we only see template nodes and no variables - something like DOM.

I've seen a similar approach to attach __loaded_blocks attribute to the parser object when dealing with block tag.

I've played around and I made a package (django-ouput-context) that implements this. It adds a parser-level context that is shared with all templates involved in making the complete output (extended and included).

The context is attached to the tempalte parser which is passed to django tags registed via @register.tag('yourtag') so you can now write your own tags that make use of this context to communicate template requirements or planned structure.

How it does this?

It overrides include and extend template tags.

However there’s a lot of code duplicated from django codebase and this is ugly.

It’s because the only thing that django_output_context do is to add a output_context parameter to all calls that start from include and extend tags down to the compile_string function that creates the parser.

Do you think something like this is worth including in Django?

Alternatively, do you know of a simpler approach than to override so much calls and therefore so much code?

Change History (4)

comment:1 by Tim Graham, 10 years ago

This type of proposal is better suited to the DevelopersMailingList where it'll reach a broader audience. I'd suggest to post it there.

comment:2 by Tim Graham, 10 years ago

Cc: Aymeric Augustin added

Aymeric, maybe you'd like to offer an opinion on this based on your template refactor research?

comment:3 by Aymeric Augustin, 10 years ago

The topic discussed here is orthogonal to my project.

I don't know enough about the internals of Django templates to comment on the proposal.

AFAICT this is the same problem that https://github.com/ojii/django-sekizai attempts to solve.

comment:4 by Tim Graham, 10 years ago

Resolution: needsinfo
Status: newclosed

Closing as "needs info" until the required discussion takes place on the mailing list and there is a consensus if we want to make a change in Django itself.

Note: See TracTickets for help on using tickets.
Back to Top