This question already has answers here:
JavaScript raises SyntaxError with data rendered in Jinja template
(3 answers)
Closed 13 days ago.
I am using Flask with Jinja2 as templating language.
How do you convert a multidimensional Python structure to a corresponding structure in javascript using Jinja2?
Example (Python/Flask):
pyStruct = [{key1:value1, key2:value2, [{subkey1:subvalue1, subkey2:subvalue2,}]},
{key1:value1, key2:value2, [{subkey1:subvalue1, subkey2:subvalue2,}]},]
render_template('jinjatemplate.html', pyStruct=pyStruct)
Example (Jinja2):
??
I guess what I'm asking is, can it only be done by creating convoluted loop constructs in Jinja2, or am I missing a shortcut somewhere?
If the answer is, yes, one has to use convoluted loops in Jinja2, then it's probably a lot easier to just create the javascript code directly in python and pass this to Jinja2 for inclusion.
But that seems to defeat the purpose of using a template language like Jinja2 somewhat...
I tried (Jinja2):
{{ pyStruct|safe }}
...and this actually works as long as nothing is unicode, and doesn't stray out of Ascii land (which it usually does in my case).
Oh, and if you wonder why pass this kind of structure? I find I often want to pass fairly complicated structures to javascript to be used by menus and other complicated selection interfaces.
You can use the json module, either as a Jinja filter ou directly passing the results of json.dumps() to your template.
pyStruct = [{key1:value1, key2:value2, [{subkey1:subvalue1, subkey2:subvalue2,}]},
{key1:value1, key2:value2, [{subkey1:subvalue1, subkey2:subvalue2,}]},]
render_template('jinjatemplate.html', json_struct=json.dumps(pyStruct))
In the template:
var myStruct = ({{ json_struct|e }});
Warning: I'm a bit unsure about the escaping bit (|e filter). You might want to check that the <, >, & characters are properly escaped with unicode escape sequences rather than xml entities.
Serialize it using json:
from django.utils import simplejson
pyStruct = [{'key1':'value1',
'key2':'value2',
'key3':[{'subkey1':'subvalue1', 'subkey2':'subvalue2'}]},
{'key1':'value1',
'key2':'value2',
'key3':[{'subkey1':'subvalue1', 'subkey2':'subvalue2'}]}]
print simplejson.dumps(pyStruct)
Flask likely has an equivalent way to json serialize data. This can also be done using loop constructs in jinja2, but is many times slower than using json.
Related
This question already has answers here:
JavaScript raises SyntaxError with data rendered in Jinja template
(3 answers)
Closed 6 years ago.
I am sitting on a Flask based webapplication. In theory I want to load a JSON file from disk and give it to javascript on the website.
def getData():
check_for_update()
with open(LOCAL_file,"rb") as myfile:
data = json.load(myfile)
udate = data["today"]
return (udate, data)
then I send it to the page with
return render_template('./index2.html', udate = thisdata[0], data = json.dumps(thisdata[1]))
Now on the page I simply try
<script>
var myjson = JSON.parse({{data}})
</script>
which then results in something like this
This can't not be parsed.When I copy and paste it it works fine, and python does not complain either.
data is HTML escaped, because Jinja2 by default escapes everything to be safe to embed in an HTML page.
It's much better to not encode to JSON in the view, do this in the template instead, and use the Flask tojson and safe filters.
So in the view pass in thisdata[1] unencoded:
return render_template(
'./index2.html', udate=thisdata[0], data=thisdata[1])
and in the view:
<script>
var myjson = {{ data|tojson|safe }};
</script>
tojson produces JSON data that is also HTML-safe (albeit with " quotes, so it is not suitable for embedding in a HTML tag attribute), and the safe filter can be used to switch off the HTML-encoding. There is no need to use JSON.parse() here, the resulting JSON produced by tojson is a strict JavaScript subset.
See the JSON Support section in the API documentation:
The htmlsafe_dumps() function of this json module is also available as filter called |tojson in Jinja2. Note that inside script tags no escaping must take place, so make sure to disable escaping with |safe if you intend to use it inside script tags[.]
and the Standard Filters section of the Flask Templates documentation:
tojson()
This function converts the given object into JSON representation. This is for example very helpful if you try to generate JavaScript on the fly.
How to pass dictionary from Jinja2 (using Python) to Javascript ?
I have dictionary in Python and when I render template I need to use that dictionary with Javascript, I passed from Python
template = JINJA_ENVIRONMENT.get_template('sm.html')
self.response.write(template.render(values=values))
but how to store them in Javascript variable inside html page.
Use the json module to turn the Python data into JSON data; JSON is a subset of JavaScript * and does fine as a JavaScript literal:
import json
js_value = json.dumps(python_value)
and render the js_value in the template.
If you need the JSON data to be HTML safe too, you'll need to add some replacements:
js_value = (json.dumps(python_value)
.replace(u'<', u'\\u003c')
.replace(u'>', u'\\u003e')
.replace(u'&', u'\\u0026')
.replace(u"'", u'\\u0027'))
*JSON allows for U+2028 and U+2029 characters which JavaScript literals can't contain, but the json.dumps() function escapes all non-ASCII codepoints by default, so provided you don't disable ensure_ascii you are fine.
You want to store it as Json. This is javascript's native format, so you can pass that directly to a variable.
I have the following JSON string as part of a log line.
cells : {"Lac":"7824","CntryISO":"us","NetTyp":"GSM","NetOp":"310260","Cid":"11983"}
I want to filter out to the following format: {"Lac":"7824","Cid":"11983"}.
How can do this using regular expression ? in Javascript or Python ?
the keys are constant strings(Lac, CntryISO, ...), but the value strings are varying.
Why don't you just delete them in JavaScript?
var myJson = {"Lac":"7824","CntryISO":"us","NetTyp":"GSM","NetOp":"310260","Cid":"11983"};
delete myJson.Lac;
delete myJson.cId;
To expand and explain #alex answer:
JSON is a nested multi dimensional structure. Simply filtering the "string-ifiyed form of a Javascript object" (aka JSON) will work in very simple cases, but will rapidly fail when the structure is no longer flat or it starts to get complex with escaped fields, etc.
At that point you will need proper parsing logic. This is nicely supplied by Javascript itself, to quote #alexes code:
var myJson = {"Lac":"7824","CntryISO":"us","NetTyp":"GSM","NetOp":"310260","Cid":"11983"};
delete myJson.Lac;
delete myJson.cId;
Or, if you want to use python, the json module will work just fine:
http://docs.python.org/library/json.html
Good luck! :)
Why would you want to use regex for this when you can just use a JSON parser/serializer? Try cjson in Python if you are concerned about speed, it is faster than 'json' module in the Python standard library.
This question already has an answer here:
How can I beautify JSON programmatically? [duplicate]
(1 answer)
Closed 10 months ago.
Possible Duplicate:
How can I beautify JSON programmatically?
I know how to generate JSON from an object using JSON.stringify, or in my case the handy jQuery JSON from Google Code.
Now this works fine, but the output is hard to read for humans. Is there an easy way, function, or whatever to output a neatly formatted JSON file?
This is what I mean:
JSON.stringify({a:1,b:2,c:{d:1,e:[1,2]}});
gives...
"{"a":1,"b":2,"c":{"d":1,"e":[1,2]}}"
I'd like something like this instead:
{
"a":1,
"b":2,
"c":{
"d":1,
"e":[1,2]
}
}
E.g., with newlines and tabs added. It's much easier to read for larger documents.
I'd like to do this ideally without adding any huge libraries, for example, not Prototype, YUI, or whatever.
JSON.stringify takes more optional arguments.
Try:
JSON.stringify({a:1,b:2,c:{d:1,e:[1,2]}}, null, 4); // Indented 4 spaces
JSON.stringify({a:1,b:2,c:{d:1,e:[1,2]}}, null, "\t"); // Indented with tab
From:
How can I beautify JSON programmatically?
It should work in modern browsers, and it is included in json2.js if you need a fallback for browsers that don't support the JSON helper functions. For display purposes, put the output in a <pre> tag to get newlines to show.
So I'm trying to use Google Map suggest API to request place name suggestions. Unfortunately I can't find the docs for this bit.
Here is an example URI:
http://maps.google.com/maps/suggest?q=lon&cp=3&ll=55.0,-3.5&spn=11.9,1.2&hl=en&gl=uk&v=2
which returns:
{suggestion:[{query:"London",...
I want to use this in python (2.5). Now in proper JSON there would have been quotations around the keys like so:
{"suggestion":[{"query":"London",...
and I could have used simplejson or something, but as it is I'm a bit stuck.
There are two possible solutions here; either I can get to the API code and find an option to return proper JSON, or I do that in python.
Any ideas please.
Ugh, that's indeed pretty annoying. It's a JavaScript literal but it — pointlessly — isn't JSON.
In theory you are supposed to be able to import json.decoder.JSONDecoder from the Python stdlib (or simplejson pre-2.6, which is the same) and subclass it, then pass that subclass to json.loads to override decoder behaviour. In reality this isn't really feasible as json.decoder is full of global cross-references that resist subclassing, and the bit you need to change is slap bang in the middle of def JSONObject.
So it's probably worth looking at other Python JSON libraries. I found this one which, in ‘non-strict’ mode, will parse unquoted object property names:
>>> import demjson
>>> demjson.decode('{suggestion:[{query:"London",interpretation: ...')
{u'suggestion': [{u'query': u'London', u'operation': 2, u'interpretation': ...
I would try to poke around in order to get JSON, but failing that there's this little monstrosity which someone will inevitably yell at me about:
class Iden(object):
def __getitem__(name, index):
return index
notjson = '{...}'
data = eval(notjson, {}, Iden())
import demjson
demjson.decode(google.js)
I found this when trying to parse Google Finance option "JSON" data, which, as many note, isn't JSON-compliant.
demjson saved me writing an obnoxious regex string; it just works.