Opened 9 years ago

Closed 9 years ago

Last modified 9 years ago

#24538 closed Bug (fixed)

Rendering a Jinja template with a context containing 'self' fails

Reported by: Tim Heap Owned by: Simon Charette
Component: Template system Version: 1.8rc1
Severity: Release blocker Keywords:
Cc: Triage Stage: Ready for checkin
Has patch: yes Needs documentation: no
Needs tests: no Patch needs improvement: no
Easy pickings: no UI/UX: no

Description

Rendering a DTL template with a context containing a 'self' key works. Attempting the same with a Jinja template fails:

from django.shortcuts import render


def self_test(request):
    # Assuming that there exists a DTL style template 'dtl.html',
    # and a Jinja template named 'jinja.html':
    render(request, 'dtl.html', {'self': 'test'})  # Works
    render(request, 'jinja.html', {'self': 'test'})   # Fails
Internal Server Error: /self_test/
Traceback (most recent call last):
  File "/home/vagrant/jinjatest_venv/local/lib/python2.7/site-packages/django/core/handlers/base.py", line 132, in get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/vagrant/jinjatest/views.py", line 6, in self_test
    render(request, 'jinja.html', {'self': 'test'})
  File "/home/vagrant/jinjatest_venv/local/lib/python2.7/site-packages/django/shortcuts.py", line 67, in render
    template_name, context, request=request, using=using)
  File "/home/vagrant/jinjatest_venv/local/lib/python2.7/site-packages/django/template/loader.py", line 99, in render_to_string
    return template.render(context, request)
  File "/home/vagrant/jinjatest_venv/local/lib/python2.7/site-packages/django/template/backends/jinja2.py", line 63, in render
    return self.template.render(**context)
TypeError: render() got multiple values for keyword argument 'self'

The Wagtail CMS uses 'self' as a key when rendering pages. This error means that Wagtail can not be used in combination with Jinja templates.

The contents of the templates is irrelevant, and can be blank for testing.

Attachments (1)

0001-Made-sure-self-can-t-be-overriden-in-Jinja.patch (2.4 KB ) - added by Simon Charette 9 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 by Simon Charette, 9 years ago

Owner: changed from nobody to Simon Charette
Severity: NormalRelease blocker
Status: newassigned
Triage Stage: UnreviewedAccepted
Type: UncategorizedBug

It should be possible to pass contex` as an arg to render() instead of **kwargs.

comment:2 by Simon Charette, 9 years ago

Resolution: invalid
Status: assignedclosed

Unfortunately it looks like a limitation of Jinja2 itself:

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from jinja2 import Environment
>>> env = Environment()
>>> template = env.from_string('{{ self }}')
>>> template.render({'self': 'Self!'})
u'<TemplateReference None>'

I think the TypeError raised here makes more sense here than silently ignoring the provided self context variable.

Attaching a test case leading to this conclusion.

comment:3 by Aymeric Augustin, 9 years ago

This patch would be excellent, if only the test passed ;-)

Could you file a bug against Jinja2?

comment:4 by Tim Heap, 9 years ago

Upon further reading, it appears that 'self' is a special variable in Jinja. From the Jinja docs:

If you want to print a block multiple times, you can, however, use the special self variable and call the block with that name:

<title>{% block title %}{% endblock %}</title>
<h1>{{ self.title() }}</h1>
{% block body %}{% endblock %}

Changing Jinja to suit this requirement is not reasonable, so I will log a bug with Wagtail CMS to rename the 'self' variable to something that can work.

comment:5 by Aymeric Augustin, 9 years ago

Resolution: invalidwontfix

Thanks for the analysis. Indeed this appears to be the right solution.

comment:6 by Tim Heap, 9 years ago

Resolution: wontfix
Status: closednew

Following some discussions on the Wagtail developer mailing list, we came up with a potential solution: use both 'self' and 'page' in the context, so that either template engine can be used, but without breaking backwards compatibility with previous Wagtail versions using self, and without breaking third party plugins.

As Jinja will silently ignore a self context variable in favour of its own, this duplicate variable approach will work. Django just has to be patched so that it does not throw an error when self is used. I will construct a pull request fixing this shortly.

comment:7 by Tim Heap, 9 years ago

A pull request has been created for this: https://github.com/django/django/pull/4415

comment:8 by Tim Graham, 9 years ago

Has patch: set
Triage Stage: AcceptedReady for checkin

comment:9 by Tim Graham <timograham@…>, 9 years ago

Resolution: fixed
Status: newclosed

In 4ea1909:

Fixed #24538 -- Allowed self in Jinja context

Rendering a Jinja template with self in the context threw an error.
While self is a reserved variable in Jinja, including self in the
context is not an error, so Django should respect that.

comment:10 by Tim Graham <timograham@…>, 9 years ago

In ff8eabc:

[1.8.x] Fixed #24538 -- Allowed self in Jinja context

Rendering a Jinja template with self in the context threw an error.
While self is a reserved variable in Jinja, including self in the
context is not an error, so Django should respect that.

Backport of 4ea1909d3c420ba1fbdbf7221cad518d43aef885 from master

comment:11 by Tim Graham <timograham@…>, 9 years ago

In a184a99:

Refs #24538 -- Simplified a test per Aymeric's feedback.

comment:12 by Tim Graham <timograham@…>, 9 years ago

In 5a4f9580:

[1.8.x] Refs #24538 -- Simplified a test per Aymeric's feedback.

Backport of a184a99123e4dc4c2a90c20e1604e5d301cd76bf from master

Note: See TracTickets for help on using tickets.
Back to Top