model = pool.get(model_str)
return lambda x: model.browse(cr, uid, x, context=context)
+def _fix_multiple_roots(node):
+ """
+ Surround the children of the ``node`` element of an XML field with a
+ single root "data" element, to prevent having a document with multiple
+ roots once parsed separately.
+
+ XML nodes should have one root only, but we'd like to support
+ direct multiple roots in our partial documents (like inherited view architectures).
+ As a convention we'll surround multiple root with a container "data" element, to be
+ ignored later when parsing.
+ """
+
+ if len(node) > 1:
+ data_node = etree.Element("data")
+ for child in node:
+ data_node.append(child)
+ node.append(data_node)
+
def _eval_xml(self, node, pool, cr, uid, idref, context=None):
if context is None:
context = {}
if not id in idref:
idref[id]=self.id_get(cr, False, id)
return s % idref
+ _fix_multiple_roots(node)
return '<?xml version="1.0"?>\n'\
+_process("".join([etree.tostring(n, encoding='utf-8')
for n in node]),
m_l = map(escape, escape_re.split(rec.get("name",'').encode('utf8')))
values = {'parent_id': False}
- if rec.get('parent', False) is False:
+ if rec.get('parent', False) is False and len(m_l) > 1:
+ # No parent attribute specified and the menu name has several menu components,
+ # try to determine the ID of the parent according to menu path
pid = False
res = None
values['name'] = m_l[-1]
pid = self.pool.get('ir.ui.menu').create(cr, self.uid, {'parent_id' : pid, 'name' : menu_elem})
values['parent_id'] = pid
else:
+ # The parent attribute was specified, if non-empty determine its ID, otherwise
+ # explicitly make a top-level menu
if rec.get('parent'):
menu_parent_id = self.id_get(cr, 'ir.ui.menu', rec.get('parent',''))
- else: # we get here with <menuitem parent="">, explicit clear of parent
+ else:
+ # we get here with <menuitem parent="">, explicit clear of parent, or
+ # if no parent attribute at all but menu name is not a menu path
menu_parent_id = False
values = {'parent_id': menu_parent_id}
if rec.get('name'):
def id_get(self, cr, model, id_str):
if id_str in self.idref:
return self.idref[id_str]
- return self.model_id_get(cr, model, id_str)[1]
+ res = self.model_id_get(cr, model, id_str)
+ if res and len(res)>1: res = res[1]
+ return res
def model_id_get(self, cr, model, id_str):
model_data_obj = self.pool.get('ir.model.data')