diff -r 34154f48d255 -r 335f14e8e5a7 utils.py --- a/utils.py Wed Jun 29 16:04:01 2011 +0200 +++ b/utils.py Wed Jun 29 16:13:09 2011 +0200 @@ -444,7 +444,7 @@ else: import json except ImportError: - json_dumps = None + json_dumps = JSString = None else: from logilab.common.date import ustrftime @@ -478,6 +478,40 @@ return json.dumps(value, cls=CubicWebJsonEncoder) + class JSString(str): + """use this string sub class in values given to :func:`js_dumps` to + insert raw javascript chain in some JSON string + """ + + def _dict2js(d, predictable=False): + res = [key + ': ' + js_dumps(val, predictable) + for key, val in d.iteritems()] + return '{%s}' % ', '.join(res) + + def _list2js(l, predictable=False): + return '[%s]' % ', '.join([js_dumps(val, predictable) for val in l]) + + def js_dumps(something, predictable=False): + """similar as :func:`json_dumps`, except values which are instances of + :class:`JSString` are expected to be valid javascript and will be output + as is + + >>> js_dumps({'hop': JSString('$.hop'), 'bar': None}, predictable=True) + '{bar: null, hop: $.hop}' + >>> js_dumps({'hop': '$.hop'}) + '{hop: "$.hop"}' + >>> js_dumps({'hip': {'hop': JSString('momo')}}) + '{hip: {hop: momo}}' + """ + if isinstance(something, dict): + return _dict2js(something, predictable) + if isinstance(something, list): + return _list2js(something, predictable) + if isinstance(something, JSString): + return something + return json_dumps(something) + + @deprecated('[3.7] merge_dicts is deprecated') def merge_dicts(dict1, dict2): """update a copy of `dict1` with `dict2`"""