#23591: RFC: Shared parser-level context to all templates involved in output
---------------------------+-----------------------------------------------
     Reporter:  antitoxic  |      Owner:  nobody
         Type:             |     Status:  new
  Uncategorized            |    Version:  1.7
    Component:  Template   |   Keywords:  template, parser, output, context
  system                   |  Has patch:  0
     Severity:  Normal     |      UI/UX:  0
 Triage Stage:             |
  Unreviewed               |
Easy pickings:  0          |
---------------------------+-----------------------------------------------
 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 ([[https://github.com/obshtestvo-
 utilities/django-output-context|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?

--
Ticket URL: <https://code.djangoproject.com/ticket/23591>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.

-- 
You received this message because you are subscribed to the Google Groups 
"Django updates" 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].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/052.43c6c6209df41bef89f592903d714363%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to