utils.py
changeset 7575 335f14e8e5a7
parent 7569 02c338197322
child 7649 ede740bd7077
--- 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`"""