#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.