[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 (?)
This commit is contained in:
parent
14a677090b
commit
2ffcff8fa9
|
@ -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(
|
||||
|
|
|
@ -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):
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue