0

I have a class view that inherits from TemplateView and sets a context variable to a serialized list of items:

class MyView(TemplateView):
  def get_context_data(self, **kwargs):
    context = super(MyView, self).get_context_data(**kwargs)
    context['items'] = serializers.serialize("json", items) # assume items is an existing list
    return context

As is noted in this post you're supposed to be able to access Django variables from our Django templates in the following manner:

<script>var items = {{ items }};</script>

However I am getting a JavaScript error, which I assume is caused because of automatic escaping:

Uncaught SyntaxError: Unexpected token &

I also tried using the filter:

<script>var items = {{ items | escapejs }};</script>

Only to find another error, this time a Django one (TemplateSyntaxError):

Could not parse the remainder: ' |  escapejs' from 'items | escapejs'

How can I solve this issue?

PS: I am using Django 1.4. (and no, I cannot upgrade it to the most recent version).

Community
  • 1
  • 1
dabadaba
  • 9,064
  • 21
  • 85
  • 155
  • 1
    try using {{ items|safe }} – sebb Sep 13 '16 at 09:52
  • Instead of passing the json through the template to your script you could add an endpoint view which serializes the data you need and request this from javascript itself with something like `$.getJSON("your_view_url", function(data) { }` – Jack Evans Sep 13 '16 at 09:55
  • @SebastianBurzyński I get the same error than with `escapejs`: `Could not parse the remainder: ' | safe' from 'items | safe'` – dabadaba Sep 13 '16 at 09:56
  • 1
    @JackEvans that's what I initially did, I ajax'ed the items as JSON in another request, but it seems redundant now, since I can do it all in just one request. – dabadaba Sep 13 '16 at 09:56
  • 1
    As Daniel said, you cannot use spaces in between your "|" sign. – sebb Sep 13 '16 at 09:58

2 Answers2

3

You can't use spaces between a template variable, the filter character, and the filter itself. So it should be {{ items|escapejs }}.

Although as Sebastian points out, you probably want {{ items|safe }} instead.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Oh wow that was it. Can you explain what were the whitespaces causing? And why should `safe` be used instead of `escapejs`? – dabadaba Sep 13 '16 at 09:58
  • The template parser is pretty basic, it just isn't clever enough to deal with spaces there. `escapejs` adds additional escaping for characters that have meaning in JS; you want the opposite, ie to pass the JSON exactly as is without escaping. – Daniel Roseman Sep 13 '16 at 10:05
1
<script>
  var items = "{{items}}";

</script>
Dimitris Kougioumtzis
  • 2,339
  • 1
  • 25
  • 36