Question

I am building a pyramid/python app where my view callable for a certain template passes in a value called data. This variable is an array in the form of [[[x1,y1,z1,],...],[[v1,v2,v3],...]]

in my viewcallable I have

import json

jsdata = json.dumps(data)

I want to put it into a javascript script tag section of my template so:

<script>
data=${jsdata}
</script>

but i'm pretty sure that syntax is incorrect. How can I do this?

Edit: from this: http://docs.pylonsproject.org/projects/pyramid/en/latest/narr/templates.html it seems that Genshi style replacements are the way to go, which I take to mean that what I have above is correct. I am still unsure however, about whether this should be treated differently because it is going inside a javascript tag. Is this true?

Was it helpful?

Solution

You want to insert a JavaScript array, not a Python list.

The easiest way to convert between Python and JavaScript formats is to use the json module. JSON is a JavaScript subset for data after all:

import json

jsdata = (json.dumps(data)
            .replace(u'<', u'\\u003c')
            .replace(u'>', u'\\u003e')
            .replace(u'&', u'\\u0026')
            .replace(u"'", u'\\u0027'))

then pass jsdata to your template instead. The str.replace() calls ensure that the data remains HTML safe.

In the template, interpolate this without escaping:

<script>
var data = ${structure:jsdata};
</script>

OTHER TIPS

I'm not sure about Chameleon, but "classical" Zope Page Templates did not allow to do anything inside script tags - if you don't see your variables interpolated it is likely that Chameleon behaves the same. The reason for this, as I understand, is to avoid exactly this type of code generation (you're generating JavaScript from Python via the template). Also, ZPT is an XML-based templating language and the content of <script> tags does not have to be a valid XML.

To work around the problem, you could do something like

jsdata = '<script type="text/javascript">var data = ' + json.dumps(data) + ';</script>'

and in your template insert the whole thing:

<tal:myscript replace="structure jsdata" />

Alternatively, you could do something like

<tal:lt replace="string:&lt;" />script>
   var data = <tal:script replace="structure jsdata" />;
<tal:lt replace="string:&lt;" />/script>

which would hide the script tags from Chameleon.

It would be a good practice to try to keep the amount of generated JavaScript in your pages as minimal as possible.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top