#35493: Allow `./` and `../` in paths when recursively including templates
-------------------------------------------+--------------------------
               Reporter:  gnpivo           |          Owner:  nobody
                   Type:  Bug              |         Status:  new
              Component:  Template system  |        Version:  5.0
               Severity:  Normal           |       Keywords:  template
           Triage Stage:  Unreviewed       |      Has patch:  0
    Needs documentation:  0                |    Needs tests:  0
Patch needs improvement:  0                |  Easy pickings:  1
                  UI/UX:  0                |
-------------------------------------------+--------------------------
 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, which is semantically
 inaccurate since the template is referencing itself and therefore
 necessarily exists.

 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
-- 
Ticket URL: <https://code.djangoproject.com/ticket/35493>
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 django-updates+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-updates/0107018fd986cfd8-d0476dc8-4bba-4dfa-b464-3f4190c4abab-000000%40eu-central-1.amazonses.com.

Reply via email to