#35493: Allow `./` and `../` in paths when recursively including templates
-------------------------------------+-------------------------------------
Reporter: Gabriel Nick | Owner: Gabriel
Pivovarov | Nick Pivovarov
Type: Bug | Status: assigned
Component: Template system | Version: 5.0
Severity: Normal | Resolution:
Keywords: template | Triage Stage:
| Unreviewed
Has patch: 1 | Needs documentation: 0
Needs tests: 1 | Patch needs improvement: 0
Easy pickings: 1 | UI/UX: 0
-------------------------------------+-------------------------------------
Description changed by Gabriel Nick Pivovarov:
Old description:
> Hi. Currently, when trying to recursively include a Django template
> within itself using the `include` tag with a path that contains `./` or
> `../`, Django raises a `TemplateSyntaxError`. However, using a path that
> does not contain `./` or `../` does not raise the error. When the error
> is raised, the debug toolbar describes it like this:
>
> > = TemplateSyntaxError at /
> >
> > The relative path ‘“./ul.html”’ was translated to template name
> ‘app/ul.html’, the same template in which the tag appears.
>
> Here is an example of a template in a Django app called `app` with the
> path `app/templates/app/ul.html` that would produce the error given
> above:
>
> {{{
> <ul>
> {% for section in sections %}
> <li>
> <p>{{ section.name }}</p>
> {% if section.sections|length != 0 %}
> {% include "./ul.html" with sections=section.sections %}
> {% endif %}
> </li>
> {% endfor %}
> </ul>
> }}}
>
> However, replacing the directory `./ul.html` with the equivalent
> `app/ul.html` makes the error go away (assuming that the project's
> `settings.py` specifies `APP_DIRS = True` and the views and URLs are
> configured correctly). The actual paths are translated identically in
> both cases, and the behavior of the `include` tag should not depend
> simply on whether or not the path string uses `./` or `../` (or if it
> should, this is not documented in the Django documentation). Therefore,
> it seems that this is a bug. The expected behavior is that an error is
> only raised when recursively using the `extends` template, not when
> recursively using the `include` template.
>
> Contrapositively, it appears that recursively extending a template using
> the `extends` tag with a path that does ''not'' contain `./` or `../`
> raises a `TemplateDoesNotExist` exception.
>
> One possible fix is to modify the `django/template/loader_tags.py` file
> (https://github.com/django/django/blob/main/django/template/loader_tags.py)
> such that the error is raised when a template attempts to extend itself
> (not when a template attempts to include itself, which would otherwise be
> valid). The error handling logic in question starts on line 267 of that
> file within the `construct_relative_path` function; perhaps it should
> live somewhere in the `do_extends` function instead.
>
> Here is a relevant discussion in the Django forums:
> https://forum.djangoproject.com/t/template-recursion-why-does-django-not-
> allow-and/31689
New description:
Hi. Currently, when trying to recursively include a Django template within
itself using the `include` tag with a path that contains `./` or `../`,
Django raises a `TemplateSyntaxError`. However, using a path that does not
contain `./` or `../` does not raise the error. When the error is raised,
the debug toolbar describes it like this:
> = TemplateSyntaxError at /
>
> The relative path ‘“./ul.html”’ was translated to template name
‘app/ul.html’, the same template in which the tag appears.
Here is an example of a template in a Django app called `app` with the
path `app/templates/app/ul.html` that would produce the error given above:
{{{
<ul>
{% for section in sections %}
<li>
<p>{{ section.name }}</p>
{% if section.sections|length != 0 %}
{% include "./ul.html" with sections=section.sections %}
{% endif %}
</li>
{% endfor %}
</ul>
}}}
However, replacing the directory `./ul.html` with the equivalent
`app/ul.html` makes the error go away (assuming that the project's
`settings.py` specifies `APP_DIRS = True` and the views and URLs are
configured correctly). The actual paths are translated identically in both
cases, and the behavior of the `include` tag should not depend simply on
whether or not the path string uses `./` or `../` (or if it should, this
is not documented in the Django documentation). Therefore, it seems that
this is a bug. The expected behavior is that an error is only raised when
recursively using the `extends` template, not when recursively using the
`include` template.
Contrapositively, it appears that recursively extending a template using
the `extends` tag with a path that does ''not'' contain `./` or `../`
raises a `TemplateDoesNotExist` exception.
One possible fix is to modify the `django/template/loader_tags.py` file
(https://github.com/django/django/blob/main/django/template/loader_tags.py)
such that the error is raised when a template attempts to extend itself
(not when a template attempts to include itself, which would otherwise be
valid). The error handling logic in question starts on line 267 of that
file within the `construct_relative_path` function; perhaps it should only
be used when called from the `do_extends` function.
Here is a relevant discussion in the Django forums:
https://forum.djangoproject.com/t/template-recursion-why-does-django-not-
allow-and/31689
--
--
Ticket URL: <https://code.djangoproject.com/ticket/35493#comment:5>
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 view this discussion on the web visit
https://groups.google.com/d/msgid/django-updates/0107018fe67adf80-62b63331-7c16-40cc-adec-84b39214fa01-000000%40eu-central-1.amazonses.com.