#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 [email protected].
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