its inherited views, by rendering it using ``fields_view_get()``.
@param browse_record view: view to validate
- @return: True if the view hierarchy was rendered without any error, False if an error occurred.
+ @return: the rendered definition (arch) of the view, always utf-8 bytestring (legacy convention)
+ if no error occurred, else False.
"""
try:
- self.pool.get(view.model).fields_view_get(cr, uid, view_id=view.id, view_type=view.type, context=context)
- return True
+ fvg = self.pool.get(view.model).fields_view_get(cr, uid, view_id=view.id, view_type=view.type, context=context)
+ return fvg['arch']
except:
_logger.exception("Can't render view %s for model: %s", view.xml_id, view.model)
return False
def _check_xml(self, cr, uid, ids, context=None):
for view in self.browse(cr, uid, ids, context):
+ # Sanity check: the view should not break anything upon rendering!
+ view_arch_utf8 = self._check_render_view(cr, uid, view, context=context)
+ # always utf-8 bytestring - legacy convention
+ if not view_arch_utf8: return False
+
# RNG-based validation is not possible anymore with 7.0 forms
- # TODO 7.0: provide alternative assertion-based validation!
- # TODO 7.0: and do the tests on the result of fields_view_get instead of each arch.
- view_docs = [etree.fromstring(view.arch.encode('utf8'))]
+ # TODO 7.0: provide alternative assertion-based validation of view_arch_utf8
+ view_docs = [etree.fromstring(view_arch_utf8)]
if view_docs[0].tag == 'data':
# A <data> element is a wrapper for multiple root nodes
view_docs = view_docs[0]
for error in validator.error_log:
_logger.error(tools.ustr(error))
return False
-
- # Second sanity check: the view should not break anything upon rendering!
- if not self._check_render_view(cr, uid, view, context=context):
- return False
return True
_constraints = [
</rng:optional>
</rng:define>
+ <rng:define name="modifiable">
+ <rng:optional>
+ <!-- @modifiers contains a JSON map unifying the various
+ modifier attributes: @readonly, @required, @invisible.
+ Each attribute is a key, mapped to a JSON list representing
+ a condition expressed as an OpenERP `domain` filter
+ Only some of the modifier keys make sense on some
+ elements, for example <filter> and <group> only support
+ `invisible`. -->
+ <rng:attribute name="modifiers"/>
+ </rng:optional>
+ </rng:define>
+
<rng:define name="access_rights">
<rng:optional>
<rng:attribute name="groups"/>
<rng:element name="label">
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
+ <rng:optional><rng:attribute name="invisible"/></rng:optional>
<rng:optional><rng:attribute name="align"/></rng:optional>
<rng:optional><rng:attribute name="nolabel"/></rng:optional>
<rng:optional><rng:attribute name="colspan"/></rng:optional>
<rng:element name="page">
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:optional><rng:attribute name="name"/></rng:optional>
<rng:optional><rng:attribute name="attrs"/></rng:optional>
<rng:element name="separator">
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
+ <rng:optional><rng:attribute name="invisible"/></rng:optional>
<rng:optional><rng:attribute name="name"/></rng:optional>
<rng:optional><rng:attribute name="colspan"/></rng:optional>
<rng:optional><rng:attribute name="rowspan"/></rng:optional>
<rng:attribute name="name" />
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
<rng:optional><rng:attribute name="domain_filter"/></rng:optional>
<rng:optional><rng:attribute name="attrs"/></rng:optional>
<rng:optional><rng:attribute name="string"/></rng:optional>
<rng:element name="group">
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
<rng:optional><rng:attribute name="attrs"/></rng:optional>
<rng:optional><rng:attribute name="colspan"/></rng:optional>
<rng:optional><rng:attribute name="rowspan"/></rng:optional>
<rng:optional><rng:attribute name="width"/></rng:optional>
<rng:optional><rng:attribute name="name"/></rng:optional>
<rng:optional><rng:attribute name="color" /></rng:optional>
+ <rng:optional><rng:attribute name="invisible"/></rng:optional>
<rng:ref name="container"/>
</rng:element>
</rng:define>
<rng:element name="button">
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
<rng:optional><rng:attribute name="attrs"/></rng:optional>
<rng:optional><rng:attribute name="invisible"/></rng:optional>
<rng:optional><rng:attribute name="name" /></rng:optional>
<rng:element name="filter">
<rng:ref name="overload"/>
<rng:ref name="access_rights"/>
+ <rng:ref name="modifiable"/>
<rng:optional><rng:attribute name="attrs"/></rng:optional>
+ <rng:optional><rng:attribute name="invisible"/></rng:optional>
<rng:optional><rng:attribute name="name" /></rng:optional>
<rng:optional><rng:attribute name="separator" /></rng:optional>
<rng:optional><rng:attribute name="icon" /></rng:optional>