#15053: Make templates more reusable by Improving template loading algorithm to
avoid extending infinite recursion
---------------------------------+----------------------------------------
Reporter: pmartin | Owner: unaizalakain
Type: New feature | Status: assigned
Component: Template system | Version: master
Severity: Normal | Resolution:
Keywords: | Triage Stage: Accepted
Has patch: 1 | Needs documentation: 0
Needs tests: 0 | Patch needs improvement: 1
Easy pickings: 0 | UI/UX: 0
---------------------------------+----------------------------------------
Comment (by prestontimmons):
I've added additional updates to my pull request. This now accounts for
the eggs and cached loaders.
After attempting multiple ways to accomplish this, I'm convinced this
feature can't happen without at least some changes to the template and
loader apis.
In my current patch, I propose the following changes:
'''Update the template loaders'''
Add a `get_sources` method to each loader. This replaces
`load_template_sources`. Instead of returning the first template found, it
yields templates until no more are found.
Add a `get_template` method to the base loader. This replaces
`load_template`. By default, this calls `get_sources` and returns the
first matching template. This takes an optional `skip` argument. This is a
list of paths to ignore. These paths are formatted as the full identifying
path for the template. For filesystem and app loaders, this is the full
path of the template.
Deprecate the `load_template_sources` and `load_template` apis. In the
meantime, 3rd-party template loaders will work as usual.
'''Update the extend tag'''
In order to handle cases such as:
{{{
filesystem/base.html -> app1/base.html -> app2/base.html -> app3/base.html
}}}
a history of which templates have already been extended needs to be kept.
The only place that has persistent access to this information is the
ExtendsNode.
Update the ExtendsNode to track the history through a context variable and
pass it as the `skip` argument to loader.get_template.
'''Add template origin always, instead of only when TEMPLATE_DEBUG is
false'''
By setting the origin, the ExtendsNode can know what the original template
is, and avoid extending itself during a recursive sequence. Without this
information, it's hard to avoid redundant recursion like:
{{{
app1/base.html -> app1/base.html -> app2/base.html -> app3/base.html
}}}
This piece of information isn't critical, but it is nice to have. Adding
it in is not unprecedented. For instance, if we were using jinja2
templates, the template source path is readily available without needing a
debug mode.
'''Update the cache loader'''
This one is problematic for allowing recursive includes. It currently
assumes that a template name maps to only a single template, and keeps it
stored in it's cache that way.
In the `cached.Loader.get_template` method, I modified the cache to store
the value as a list of template instead. This is calculated once when a
new template is passed in.
I think this is reasonable but it could use some review.
--
Ticket URL: <https://code.djangoproject.com/ticket/15053#comment:45>
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/065.a7081370d980c67bb1a93208b7d6e8d7%40djangoproject.com.
For more options, visit https://groups.google.com/d/optout.