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