summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorXavier Morel <xmo@openerp.com>2014-09-11 08:38:08 +0200
committerXavier Morel <xmo@openerp.com>2014-10-06 19:13:44 +0200
commit2ffcff8fa9bd58beee33170be5a11649ec282602 (patch)
tree167ead2b9aa1f49b98782f6843464bf6fdabf49d
parent14a677090bacea426152b7287d20a00155415c8e (diff)
[ADD] qweb: handling of t-att=mapping
Changed render_att_att to return an iterable of pairs instead of a pair, and dispatched t-att on whether its result is a Mapping. Also changed qweb test runner so it uses ordereddict for JSON mapping in params, otherwise iteration order (and thus order of attributes in output) is unpredictable and results don't/can't match expectations (as both are strings). Note that this relies on JS implementation details wrt iteration order of mappings. Tests would probably be somewhat less brittle if rendering output was parsed to XML... if that's possible (?)
-rw-r--r--addons/website/models/ir_qweb.py10
-rw-r--r--openerp/addons/base/ir/ir_qweb.py26
-rw-r--r--openerp/addons/base/tests/test_qweb.py5
3 files changed, 26 insertions, 15 deletions
diff --git a/addons/website/models/ir_qweb.py b/addons/website/models/ir_qweb.py
index 40b85fda697..c598773c10b 100644
--- a/addons/website/models/ir_qweb.py
+++ b/addons/website/models/ir_qweb.py
@@ -56,11 +56,13 @@ class QWeb(orm.AbstractModel):
super(QWeb, self).add_template(qcontext, name, node)
def render_att_att(self, element, attribute_name, attribute_value, qwebcontext):
- att, val = super(QWeb, self).render_att_att(element, attribute_name, attribute_value, qwebcontext)
+ URL_ATTRS = self.URL_ATTRS.get(element.tag)
+ is_website = request.website
+ for att, val in super(QWeb, self).render_att_att(element, attribute_name, attribute_value, qwebcontext):
+ if is_website and att == URL_ATTRS and isinstance(val, basestring):
+ val = qwebcontext.get('url_for')(val)
+ yield (att, val)
- if request.website and att == self.URL_ATTRS.get(element.tag) and isinstance(val, basestring):
- val = qwebcontext.get('url_for')(val)
- return att, val
def get_converter_for(self, field_type):
return self.pool.get(
diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py
index d91d4cd5d02..1508baff9d8 100644
--- a/openerp/addons/base/ir/ir_qweb.py
+++ b/openerp/addons/base/ir/ir_qweb.py
@@ -265,8 +265,12 @@ class QWeb(orm.AbstractModel):
if attribute_name.startswith("t-"):
for attribute in self._render_att:
if attribute_name[2:].startswith(attribute):
- att, val = self._render_att[attribute](self, element, attribute_name, attribute_value, qwebcontext)
- if val:
+ attrs = self._render_att[attribute](
+ self, element, attribute_name, attribute_value, qwebcontext)
+ for att, val in attrs:
+ if not val: continue
+ if not isinstance(val, str):
+ val = unicode(val).encode('utf-8')
generated_attributes += self.render_attribute(element, att, val, qwebcontext)
break
else:
@@ -336,14 +340,16 @@ class QWeb(orm.AbstractModel):
# Attributes
def render_att_att(self, element, attribute_name, attribute_value, qwebcontext):
if attribute_name.startswith("t-attf-"):
- att, val = attribute_name[7:], self.eval_format(attribute_value, qwebcontext)
- elif attribute_name.startswith("t-att-"):
- att, val = attribute_name[6:], self.eval(attribute_value, qwebcontext)
- else:
- att, val = self.eval_object(attribute_value, qwebcontext)
- if val and not isinstance(val, str):
- val = unicode(val).encode("utf8")
- return att, val
+ return [(attribute_name[7:], self.eval_format(attribute_value, qwebcontext))]
+
+ if attribute_name.startswith("t-att-"):
+ return [(attribute_name[6:], self.eval(attribute_value, qwebcontext))]
+
+ result = self.eval_object(attribute_value, qwebcontext)
+ if isinstance(result, collections.Mapping):
+ return result.iteritems()
+ # assume tuple
+ return [result]
# Tags
def render_tag_raw(self, element, template_attributes, generated_attributes, qwebcontext):
diff --git a/openerp/addons/base/tests/test_qweb.py b/openerp/addons/base/tests/test_qweb.py
index a923a835402..9ac4388cbe2 100644
--- a/openerp/addons/base/tests/test_qweb.py
+++ b/openerp/addons/base/tests/test_qweb.py
@@ -4,6 +4,7 @@ import json
import os.path
import glob
import re
+import collections
from lxml import etree
import openerp.addons.base.ir.ir_qweb
@@ -118,7 +119,9 @@ class TestQWeb(common.TransactionCase):
for template in context.templates:
if template.startswith('_'): continue
param = doc.find('params[@id="{}"]'.format(template))
- params = {} if param is None else json.loads(param.text)
+ # OrderedDict to ensure JSON mappings are iterated in source order
+ # so output is predictable & repeatable
+ params = {} if param is None else json.loads(param.text, object_pairs_hook=collections.OrderedDict)
ctx = context.copy()
ctx.update(params)