diff --git a/addons/website/controllers/main.py b/addons/website/controllers/main.py index ab024e1819741b5c0cd98d96762442e863afe9da..39f3067720f5dcdc6125a29cb6f27f4874c56a82 100644 --- a/addons/website/controllers/main.py +++ b/addons/website/controllers/main.py @@ -158,22 +158,25 @@ class Website(openerp.addons.web.controllers.main.Home): @http.route('/website/theme_change', type='http', auth="user", website=True) def theme_change(self, theme_id=False, **kwargs): imd = request.registry['ir.model.data'] - view = request.registry['ir.ui.view'] + Views = request.registry['ir.ui.view'] - view_model, view_option_id = imd.get_object_reference( + _, theme_template_id = imd.get_object_reference( request.cr, request.uid, 'website', 'theme') - views = view.search( - request.cr, request.uid, [('inherit_id', '=', view_option_id)], - context=request.context) - view.write(request.cr, request.uid, views, {'inherit_id': False}, - context=request.context) + views = Views.search(request.cr, request.uid, [ + ('inherit_id', '=', theme_template_id), + ('application', '=', 'enabled'), + ], context=request.context) + Views.write(request.cr, request.uid, views, { + 'application': 'disabled', + }, context=request.context) if theme_id: module, xml_id = theme_id.split('.') - view_model, view_id = imd.get_object_reference( + _, view_id = imd.get_object_reference( request.cr, request.uid, module, xml_id) - view.write(request.cr, request.uid, [view_id], - {'inherit_id': view_option_id}, context=request.context) + Views.write(request.cr, request.uid, [view_id], { + 'application': 'enabled' + }, context=request.context) return request.render('website.themes', {'theme_changed': True}) @@ -197,54 +200,45 @@ class Website(openerp.addons.web.controllers.main.Home): module_obj.button_immediate_upgrade(request.cr, request.uid, module_ids, context=request.context) return request.redirect(redirect) - @http.route('/website/customize_template_toggle', type='json', auth='user', website=True) - def customize_template_set(self, view_id): - view_obj = request.registry.get("ir.ui.view") - view = view_obj.browse(request.cr, request.uid, int(view_id), - context=request.context) - if view.inherit_id: - value = False - else: - value = view.inherit_option_id and view.inherit_option_id.id or False - view_obj.write(request.cr, request.uid, [view_id], { - 'inherit_id': value - }, context=request.context) - return True - @http.route('/website/customize_template_get', type='json', auth='user', website=True) - def customize_template_get(self, xml_id, optional=True): + def customize_template_get(self, xml_id, full=False): + """ Lists the templates customizing ``xml_id``. By default, only + returns optional templates (which can be toggled on and off), if + ``full=True`` returns all templates customizing ``xml_id`` + """ imd = request.registry['ir.model.data'] view_model, view_theme_id = imd.get_object_reference( request.cr, request.uid, 'website', 'theme') - user = request.registry['res.users'].browse(request.cr, request.uid, request.uid, request.context) - group_ids = [g.id for g in user.groups_id] + user = request.registry['res.users']\ + .browse(request.cr, request.uid, request.uid, request.context) + user_groups = set(user.groups_id) - view = request.registry.get("ir.ui.view") - views = view._views_get(request.cr, request.uid, xml_id, context=request.context) - done = {} + views = request.registry["ir.ui.view"]\ + ._views_get(request.cr, request.uid, xml_id, context=request.context) + done = set() result = [] for v in views: - if v.groups_id and [g for g in v.groups_id if g.id not in group_ids]: + if not user_groups.issuperset(v.groups_id): continue - if v.inherit_option_id and v.inherit_option_id.id != view_theme_id or not optional: - if v.inherit_option_id.id not in done: + if full or (v.application != 'always' and v.inherit_id.id != view_theme_id): + if v.inherit_id not in done: result.append({ - 'name': v.inherit_option_id.name, + 'name': v.inherit_id.name, 'id': v.id, 'xml_id': v.xml_id, 'inherit_id': v.inherit_id.id, 'header': True, 'active': False }) - done[v.inherit_option_id.id] = True + done.add(v.inherit_id) result.append({ 'name': v.name, 'id': v.id, 'xml_id': v.xml_id, 'inherit_id': v.inherit_id.id, 'header': False, - 'active': (v.inherit_id.id == v.inherit_option_id.id) or (not optional and v.inherit_id.id) + 'active': v.application in ('always', 'enabled'), }) return result diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 9d89665c56f4f592a7e56dd69dcc92985c136430..398bbb6a87b92435e6ed41bb3056fa5f876b0ce9 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -13,8 +13,6 @@ from openerp.osv import osv, fields class view(osv.osv): _inherit = "ir.ui.view" _columns = { - 'inherit_option_id': fields.many2one('ir.ui.view','Optional Inheritancy'), - 'inherited_option_ids': fields.one2many('ir.ui.view','inherit_option_id','Optional Inheritancies'), 'page': fields.boolean("Whether this view is a web page template (complete)"), 'website_meta_title': fields.char("Website meta title", size=70, translate=True), 'website_meta_description': fields.text("Website meta description", size=160, translate=True), @@ -24,25 +22,30 @@ class view(osv.osv): 'page': False, } + + def _view_obj(self, cr, uid, view_id, context=None): + if isinstance(view_id, basestring): + return self.pool['ir.model.data'].xmlid_to_object( + cr, uid, view_id, raise_if_not_found=True, context=context + ) + elif isinstance(view_id, (int, long)): + return self.browse(cr, uid, view_id, context=context) + + # assume it's already a view object (WTF?) + return view_id + # Returns all views (called and inherited) related to a view # Used by translation mechanism, SEO and optional templates - def _views_get(self, cr, uid, view, options=True, context=None, root=True, stack_result=None): - if not context: - context = {} - if not stack_result: - stack_result = [] - - def view_obj(view): - if isinstance(view, basestring): - mod_obj = self.pool.get("ir.model.data") - m, n = view.split('.') - view = mod_obj.get_object(cr, uid, m, n, context=context) - elif isinstance(view, (int, long)): - view = self.pool.get("ir.ui.view").browse(cr, uid, view, context=context) - return view + def _views_get(self, cr, uid, view_id, options=True, context=None, root=True): + """ For a given view ``view_id``, should return: + * the view itself + * all views inheriting from it, enabled or not + - but not the optional children of a non-enabled child + * all views called from it (via t-call) + """ try: - view = view_obj(view) + view = self._view_obj(cr, uid, view_id, context=context) except ValueError: # Shall we log that ? return [] @@ -55,19 +58,25 @@ class view(osv.osv): node = etree.fromstring(view.arch) for child in node.xpath("//t[@t-call]"): try: - call_view = view_obj(child.get('t-call')) + called_view = self._view_obj(cr, uid, child.get('t-call'), context=context) except ValueError: continue - if call_view not in result: - result += self._views_get(cr, uid, call_view, options=options, context=context, stack_result=result) - - todo = view.inherit_children_ids - if options: - todo += filter(lambda x: not x.inherit_id, view.inherited_option_ids) - # Keep options in a determinitic order whatever their enabled disabled status - todo.sort(lambda x,y:cmp(x.id,y.id)) - for child_view in todo: - for r in self._views_get(cr, uid, child_view, options=bool(child_view.inherit_id), context=context, root=False, stack_result=result): + if called_view not in result: + result += self._views_get(cr, uid, called_view, options=options, context=context) + + extensions = view.inherit_children_ids + if not options: + # only active children + extensions = (v for v in view.inherit_children_ids + if v.application in ('always', 'enabled')) + + # Keep options in a deterministic order regardless of their applicability + for extension in sorted(extensions, key=lambda v: v.id): + for r in self._views_get( + cr, uid, extension, + # only return optional grandchildren if this child is enabled + options=extension.application in ('always', 'enabled'), + context=context, root=False): if r not in result: result.append(r) return result diff --git a/addons/website/static/src/js/website.ace.js b/addons/website/static/src/js/website.ace.js index a8af74bb52d05d82667e7005bc58ddc9f975470c..27e5cd60e62ad6133b0e58ff7b5a8d999f5d645f 100644 --- a/addons/website/static/src/js/website.ace.js +++ b/addons/website/static/src/js/website.ace.js @@ -97,7 +97,7 @@ var viewId = $(document.documentElement).data('view-xmlid'); openerp.jsonRpc('/website/customize_template_get', 'call', { 'xml_id': viewId, - 'optional': false, + 'full': true, }).then(function (views) { self.loadViews.call(self, views); self.open.call(self); diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 595df04a08871d7a3d61a3922cf663b8dfa90336..fcb957cafda75beca63152a45e50753f8caba4c0 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -470,8 +470,14 @@ }); menu.on('click', 'a[data-action!=ace]', function (event) { var view_id = $(event.currentTarget).data('view-id'); - openerp.jsonRpc('/website/customize_template_toggle', 'call', { - 'view_id': view_id + return openerp.jsonRpc('/web/dataset/call_kw', 'call', { + model: 'ir.ui.view', + method: 'toggle', + args: [], + kwargs: { + ids: [parseInt(view_id, 10)], + context: website.get_context() + } }).then( function() { window.location.reload(); }); diff --git a/addons/website/views/themes.xml b/addons/website/views/themes.xml index 82f5105adcddd9b1f76b9c5390321e2e973564de..a240813320728100f94292451289171fb1d068bb 100644 --- a/addons/website/views/themes.xml +++ b/addons/website/views/themes.xml @@ -203,82 +203,82 @@ All Default Themes --> - <template id="website.theme_amelia" name="Amelia" inherit_option_id="website.theme"> + <template id="website.theme_amelia" name="Amelia" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/amelia.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/amelia.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_cerulean" name="Cerulean" inherit_option_id="website.theme"> + <template id="website.theme_cerulean" name="Cerulean" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/cerulean.min.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_cosmo" name="Cosmo" inherit_option_id="website.theme"> + <template id="website.theme_cosmo" name="Cosmo" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/cosmo.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/cosmo.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_cyborg" name="Cyborg" inherit_option_id="website.theme"> + <template id="website.theme_cyborg" name="Cyborg" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/cyborg.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/cyborg.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_flatly" name="Flatly" inherit_option_id="website.theme"> + <template id="website.theme_flatly" name="Flatly" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/flatly.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/flatly.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_journal" name="Journal" inherit_option_id="website.theme"> + <template id="website.theme_journal" name="Journal" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/journal.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/journal.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_readable" name="Readable" inherit_option_id="website.theme"> + <template id="website.theme_readable" name="Readable" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/readable.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/readable.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_simplex" name="Simplex" inherit_option_id="website.theme"> + <template id="website.theme_simplex" name="Simplex" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/simplex.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/simplex.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_slate" name="Slate" inherit_option_id="website.theme"> + <template id="website.theme_slate" name="Slate" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/slate.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/slate.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_spacelab" name="Spacelab" inherit_option_id="website.theme"> + <template id="website.theme_spacelab" name="Spacelab" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/spacelab.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/spacelab.fix.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_united" name="United" inherit_option_id="website.theme"> + <template id="website.theme_united" name="United" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/united.min.css' t-ignore="true"/> </xpath> </template> - <template id="website.theme_yeti" name="Yeti" inherit_option_id="website.theme"> + <template id="website.theme_yeti" name="Yeti" inherit_id="website.theme" optional="disabled"> <xpath expr="//link[@id='bootstrap_css']" position="replace"> <link rel='stylesheet' href='/website/static/src/css/bootswatch/yeti.min.css' t-ignore="true"/> <link rel='stylesheet' href='/website/static/src/css/bootswatch/yeti.fix.css' t-ignore="true"/> diff --git a/addons/website/views/website_templates.xml b/addons/website/views/website_templates.xml index d5aebd4c68677da092de880a48f61ea21a08034d..6226e3a0aa7d091b9c8ed965a27fb82e2ba70ebd 100644 --- a/addons/website/views/website_templates.xml +++ b/addons/website/views/website_templates.xml @@ -220,7 +220,7 @@ </html> </template> -<template id="layout_logo_show" inherit_id="website.layout" inherit_option_id="website.layout" name="Show Logo"> +<template id="layout_logo_show" inherit_id="website.layout" optional="enabled" name="Show Logo"> <xpath expr="//header//a[@class='navbar-brand']" position="replace"> <a href="/" class="navbar-brand logo"> <img src="/logo.png"/> @@ -304,7 +304,7 @@ <script type="text/javascript" src="/website/static/src/js/jQuery.transfo.js"></script> </template> -<template id="debugger" inherit_option_id="website.layout" name="Debugger & Tests"> +<template id="debugger" inherit_id="website.layout" optional="disabled" name="Debugger & Tests"> <xpath expr='//t[@name="layout_head"]' position="after"> <script type="text/javascript" src="/website/static/src/js/website.tour.js"></script> </xpath> @@ -318,7 +318,7 @@ </xpath> </template> -<template id="show_sign_in" inherit_option_id="website.layout" inherit_id="website.layout" name="Show Sign In" groups="base.group_public"> +<template id="show_sign_in" optional="enabled" inherit_id="website.layout" name="Show Sign In" groups="base.group_public"> <xpath expr="//ul[@id='top_menu']" position="inside"> <li class="divider"/> <li> @@ -329,7 +329,7 @@ </xpath> </template> -<template id="footer_custom" inherit_option_id="website.layout" name="Custom Footer"> +<template id="footer_custom" inherit_id="website.layout" optional="disabled" name="Custom Footer"> <xpath expr="//div[@id='footer_container']" position="before"> <div class="oe_structure"> <section data-snippet-id='three-columns' class="mt16 mb16"> diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index 884c638a3ef798c4b0c622b255247e697820cdf3..e6f93dc8779964720f210e6b4853757c8ce70afc 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -161,7 +161,7 @@ <!-- Option: Blog Post List: show tags --> <template id="opt_blog_post_short_tags" name="Tags" - inherit_option_id="website_blog.blog_post_short" inherit_id="website_blog.blog_post_short"> + optional="enabled" inherit_id="website_blog.blog_post_short"> <xpath expr="//div[@name='blog_post_data']" position="inside"> <p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)"> <span class="fa fa-tags"/> @@ -265,7 +265,7 @@ <!-- Options: Blog Post: breadcrumb --> <template id="blog_breadcrumb" name="Breadcrumb" - inherit_option_id="website_blog.blog_post_complete"> + inherit_id="website_blog.blog_post_complete" optional="disabled"> <xpath expr="//div[@id='title']" position="before"> <div class="container"> <div class="row"> @@ -285,7 +285,7 @@ <!-- Options: Blog Post: user can reply --> <template id="opt_blog_post_complete_comment" name="Allow blog post comment" - inherit_option_id="website_blog.blog_post_complete" + inherit_id="website_blog.blog_post_complete" optional="disabled" groups="website_mail.group_comment"> <xpath expr="//ul[@id='comments-list']" position="before"> <section class="mb32 read_width css_editable_mode_hidden"> @@ -307,7 +307,7 @@ <!-- Options: Blog Post: user can select text for tweet --> <template id="opt_blog_post_select_to_tweet" name="Select to Tweet" - inherit_option_id="website_blog.blog_post_complete"> + inherit_id="website_blog.blog_post_complete" optional="disabled"> <xpath expr="//div[@id='blog_content']" position="attributes"> <attribute name="class">js_tweet mt32</attribute> </xpath> @@ -318,7 +318,7 @@ <!-- Options: Blog Post: user can add Inline Discussion --> <template id="opt_blog_post_inline_discussion" name="Allow comment in text" - inherit_option_id="website_blog.blog_post_complete"> + inherit_id="website_blog.blog_post_complete" optional="disabled"> <xpath expr="//div[@id='blog_content']" position="attributes"> <attribute name="enable_chatter_discuss">True</attribute> </xpath> @@ -326,7 +326,7 @@ <!-- Options: Blog Post: show tags --> <template id="opt_blog_post_complete_tags" name="Tags" - inherit_option_id="website_blog.blog_post_complete" inherit_id="website_blog.blog_post_complete"> + optional="enabled" inherit_id="website_blog.blog_post_complete"> <xpath expr="//p[@name='blog_post_data']" position="after"> <p class="post-meta text-muted text-center" t-if="len(blog_post.tag_ids)"> <span class="fa fa-tags"/> @@ -355,7 +355,7 @@ <!-- Option:Right Column for extra info --> <template id="index_right" name="Right Column" - inherit_option_id="website_blog.blog_post_short"> + inherit_id="website_blog.blog_post_short" optional="disabled"> <xpath expr="//div[@id='main_column']" position="attributes"> <attribute name="class">col-sm-8</attribute> </xpath> @@ -366,7 +366,7 @@ <!-- Option:Right Column: tags --> <template id="opt_blog_rc_tags" name="Tags" - inherit_option_id="website_blog.index_right"> + inherit_id="website_blog.index_right" optional="disabled"> <xpath expr="//div[@id='blog_right_column']" position="inside"> <section class="mt32"> <h4>Tags</h4> @@ -383,7 +383,7 @@ <!-- Option:Right Column: archives --> <template id="opt_blog_rc_history" name="Archives" - inherit_option_id="website_blog.index_right"> + inherit_id="website_blog.index_right" optional="disabled"> <xpath expr="//div[@id='blog_right_column']" position="inside"> <section class="mt32"> <h4>Archives</h4> @@ -400,7 +400,7 @@ <!-- Option:Right Column: about us --> <template id="opt_blog_rc_about_us" name="About Us" priority="2" - inherit_option_id="website_blog.index_right"> + inherit_id="website_blog.index_right" optional="disabled"> <xpath expr="//div[@id='blog_right_column']" position="inside"> <section class="mt32"> <h4>About us</h4> @@ -417,7 +417,7 @@ <!-- Option:Right Column: follow us --> <template id="opt_blog_rc_follow_us" name="Follow us" priority="4" - inherit_option_id="website_blog.index_right"> + inherit_id="website_blog.index_right" optional="disabled"> <xpath expr="//div[@id='blog_right_column']" position="inside"> <section class="mt32"> <h4>Follow us<small t-if="blog">: <t t-esc="blog.name"/></small></h4> @@ -444,7 +444,7 @@ <!-- Option:Right Column: blogs --> <template id="opt_blog_rc_blogs" name="Our Blogs" priority="6" - inherit_option_id="website_blog.index_right"> + inherit_id="website_blog.index_right" optional="disabled"> <xpath expr="//div[@id='blog_right_column']" position="inside"> <section class="mt32 mb32"> <h4>Our Blogs</h4> diff --git a/addons/website_crm/views/website_crm.xml b/addons/website_crm/views/website_crm.xml index a521e155b02baf01f00da5f4f6a120bc6b604faf..1f845c42d5457c9f7eef2cd9f862dfdd63ae64b0 100644 --- a/addons/website_crm/views/website_crm.xml +++ b/addons/website_crm/views/website_crm.xml @@ -2,7 +2,7 @@ <openerp> <data> -<template id="contactus_form" name="Contact Form" inherit_id="website.contactus" inherit_option_id="website.contactus"> +<template id="contactus_form" name="Contact Form" inherit_id="website.contactus" optional="enabled"> <xpath expr="//div[@name='mail_button']" position="replace"> <form action="/crm/contactus" method="post" class="form-horizontal mt32" enctype="multipart/form-data"> <t t-foreach="kwargs" t-as="kwarg"> @@ -47,7 +47,7 @@ </xpath> </template> -<template id="contactus_form_company_name" name="Company Name" inherit_id="website_crm.contactus_form" inherit_option_id="website_crm.contactus_form"> +<template id="contactus_form_company_name" name="Company Name" inherit_id="website_crm.contactus_form" optional="enabled"> <xpath expr="//div[@name='email_from_container']" position="after"> <div t-attf-class="form-group #{error and 'partner_name' in error and 'has-error' or ''}"> <label class="col-md-3 col-sm-4 control-label" for="partner_name">Your Company</label> diff --git a/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml b/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml index 6d5b93793adc2a8cb7288b59e7f019a4d09efefe..f960511edfc35df730721aa187b9342e0881d18e 100644 --- a/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml +++ b/addons/website_crm_partner_assign/views/website_crm_partner_assign.xml @@ -113,7 +113,7 @@ </t> </template> -<template id="ref_country" inherit_id="website_crm_partner_assign.index" inherit_option_id="website_crm_partner_assign.index" name="Left World Map"> +<template id="ref_country" inherit_id="website_crm_partner_assign.index" optional="enabled" name="Left World Map"> <xpath expr="//ul[@id='reseller_countries']" position="after"> <h3>World Map</h3> <ul class="nav"> diff --git a/addons/website_customer/views/website_customer.xml b/addons/website_customer/views/website_customer.xml index a41d5b77f5a79c8703500dab3994651cbf6d39ac..efe19b5b973bba7992b71a77236af80156221da1 100644 --- a/addons/website_customer/views/website_customer.xml +++ b/addons/website_customer/views/website_customer.xml @@ -66,7 +66,7 @@ </template> <!-- Option: left column: World Map --> -<template id="opt_country" inherit_option_id="website_customer.index" name="Show Map"> +<template id="opt_country" inherit_id="website_customer.index" optional="disabled" name="Show Map"> <xpath expr="//div[@id='ref_left_column']" position="inside"> <iframe t-attf-src="/google_map/?partner_ids=#{ google_map_partner_ids }&partner_url=/customers/&output=embed" @@ -74,7 +74,7 @@ </xpath> </template> -<template id="opt_country_list" inherit_id="website_customer.index" inherit_option_id="website_customer.index" name="Filter on Countries"> +<template id="opt_country_list" inherit_id="website_customer.index" optional="enabled" name="Filter on Countries"> <xpath expr="//div[@id='ref_left_column']" position="inside"> <h3>References by Country</h3> <ul class="nav nav-pills nav-stacked mt16 mb32"> diff --git a/addons/website_event/views/website_event.xml b/addons/website_event/views/website_event.xml index d38d49036e471a90a3a038202de010569038bf5c..4585c30eb1c84daa7529854a503a39001dc38c08 100644 --- a/addons/website_event/views/website_event.xml +++ b/addons/website_event/views/website_event.xml @@ -87,7 +87,7 @@ </t> </template> -<template id="event_right_photos" inherit_option_id="website_event.index" name="Photos"> +<template id="event_right_photos" inherit_id="website_event.index" optional="disabled" name="Photos"> <xpath expr="//div[@id='right_column']" position="inside"> <div class="row"> <div class="col-md-12 mb16"> @@ -106,7 +106,7 @@ </xpath> </template> -<template id="event_right_quotes" inherit_option_id="website_event.index" name="Quotes"> +<template id="event_right_quotes" inherit_id="website_event.index" optional="disabled" name="Quotes"> <xpath expr="//div[@id='right_column']" position="inside"> <div class="row"> <div class="col-md-12 mb16"> @@ -123,7 +123,7 @@ </xpath> </template> -<template id="event_right_country_event" inherit_option_id="website_event.index" name="Country Events"> +<template id="event_right_country_event" inherit_id="website_event.index" optional="disabled" name="Country Events"> <xpath expr="//div[@id='right_column']" position="inside"> <div class="row"> <div class="col-md-12 mb16 mt16 country_events"> @@ -140,7 +140,7 @@ </xpath> </template> -<template id="event_left_column" inherit_option_id="website_event.index" inherit_id="website_event.index" name="Filters"> +<template id="event_left_column" optional="enabled" inherit_id="website_event.index" name="Filters"> <xpath expr="//div[@id='middle_column']" position="attributes"> <attribute name="class">col-md-6</attribute> </xpath> @@ -159,7 +159,7 @@ </xpath> </template> -<template id="event_category" inherit_option_id="website_event.event_left_column" name="Filter by Category"> +<template id="event_category" inherit_id="website_event.event_left_column" optional="disabled" name="Filter by Category"> <xpath expr="//div[@id='left_column']" position="inside"> <ul class="nav nav-pills nav-stacked mt32"> <t t-foreach="types"> @@ -173,7 +173,7 @@ </xpath> </template> -<template id="event_location" inherit_option_id="website_event.event_left_column" name="Filter by Country"> +<template id="event_location" inherit_id="website_event.event_left_column" optional="disabled" name="Filter by Country"> <xpath expr="//div[@id='left_column']" position="inside"> <ul class="nav nav-pills nav-stacked mt32"> <t t-foreach="countries"> diff --git a/addons/website_event_sale/views/website_event_sale.xml b/addons/website_event_sale/views/website_event_sale.xml index b2f5d2a78f5bfef770f380eb76482018237fc0dd..967d9c029ccfda9edae807187f6eb0917ecba133 100644 --- a/addons/website_event_sale/views/website_event_sale.xml +++ b/addons/website_event_sale/views/website_event_sale.xml @@ -26,7 +26,7 @@ </xpath> </template> -<template id="event_description_full" inherit_id="website_event.event_description_full" inherit_option_id="website_event.event_description_full" name="Event's Ticket form"> +<template id="event_description_full" inherit_id="website_event.event_description_full" optional="enabled" name="Event's Ticket form"> <xpath expr="//div[@t-field='event.description']" position="before"> <form t-attf-action="/event/cart/update?event_id=#{ event.id }" method="post" t-if="event.event_ticket_ids"> <table itemprop="offers" class="table table-striped"> diff --git a/addons/website_event_track/views/website_event.xml b/addons/website_event_track/views/website_event.xml index 45531ef73b0518e62c482dd9885c64f6d0fb40fe..cb5140282664bfc83a435d45740dbd9b51f27a05 100644 --- a/addons/website_event_track/views/website_event.xml +++ b/addons/website_event_track/views/website_event.xml @@ -2,7 +2,7 @@ <openerp> <data> -<template name="Sponsors" id="event_sponsor" inherit_option_id="website_event.layout" inherit_id="website_event.layout"> +<template name="Sponsors" id="event_sponsor" optional="enabled" inherit_id="website_event.layout"> <xpath expr="//t[@t-call='website.layout']" position="inside"> <t t-set="head"> <link rel='stylesheet' href='/website_event_track/static/src/css/website_event_track.css'/> @@ -157,7 +157,7 @@ </t> </template> -<template id="tracks_filter" inherit_id="website_event_track.tracks" inherit_option_id="website_event_track.tracks" name="Filter on Tags"> +<template id="tracks_filter" inherit_id="website_event_track.tracks" optional="enabled" name="Filter on Tags"> <xpath expr="//div[@id='left_column']" position="inside"> <ul class="nav nav-pills nav-stacked"> <li t-att-class="'' if searches.get('tag') else 'active'"><a t-attf-href="/event/#{ slug(event) }/track">All Tags</a></li> @@ -246,7 +246,7 @@ </t> </template> -<template id="event_track_social" name="Social Widgets" inherit_option_id="website_event_track.track_view"> +<template id="event_track_social" name="Social Widgets" inherit_id="website_event_track.track_view" optional="disabled"> <xpath expr="//div[@id='right_column']" position="inside"> <div class="panel panel-default"> <div class="panel-heading"> diff --git a/addons/website_hr/views/website_hr.xml b/addons/website_hr/views/website_hr.xml index 357328c83497878e47413131d3273ac46baa5158..74324294d945cc9a6d9bfbb957bd77b7ce54c69d 100644 --- a/addons/website_hr/views/website_hr.xml +++ b/addons/website_hr/views/website_hr.xml @@ -3,7 +3,7 @@ <data> <!-- Page --> -<template id="aboutus" inherit_id="website.aboutus" inherit_option_id="website.aboutus" name="Our Team"> +<template id="aboutus" inherit_id="website.aboutus" optional="enabled" name="Our Team"> <xpath expr="//div[@class='oe_structure']" position="after"> <section class="container"> <div class="col-sm-12 text-center" t-if="len(employee_ids)"> diff --git a/addons/website_hr_recruitment/views/templates.xml b/addons/website_hr_recruitment/views/templates.xml index 6255b188a4042c16610c295c93a33e308d038146..2c31f26b8dcf91f2bcae572f35ffb13473ae548e 100644 --- a/addons/website_hr_recruitment/views/templates.xml +++ b/addons/website_hr_recruitment/views/templates.xml @@ -230,7 +230,7 @@ </t> </template> -<template id="job_departments" inherit_option_id="website_hr_recruitment.index" name="Filter by Departments"> +<template id="job_departments" inherit_id="website_hr_recruitment.index" optional="disabled" name="Filter by Departments"> <xpath expr="//div[@id='jobs_grid_left']" position="inside"> <ul class="nav nav-pills nav-stacked mb32"> <li t-att-class=" '' if department_id else 'active' "><a href="/jobs">All Departments</a></li> @@ -249,7 +249,7 @@ </xpath> </template> -<template id="job_offices" inherit_option_id="website_hr_recruitment.index" name="Filter by Offices"> +<template id="job_offices" inherit_id="website_hr_recruitment.index" optional="disabled" name="Filter by Offices"> <xpath expr="//div[@id='jobs_grid_left']" position="inside"> <ul class="nav nav-pills nav-stacked mb32"> <li t-att-class=" '' if office_id else 'active' "><a href="/jobs">All Offices</a></li> diff --git a/addons/website_membership/views/website_membership.xml b/addons/website_membership/views/website_membership.xml index ca38873c0d0d9d6872db493211d4438d0a5e489b..d10f5a933e2fcd159ff7bf0209034c90a5ed41db 100644 --- a/addons/website_membership/views/website_membership.xml +++ b/addons/website_membership/views/website_membership.xml @@ -84,7 +84,7 @@ </template> <template id="opt_index_country" name="Location" - inherit_option_id="website_membership.index" inherit_id="website_membership.index"> + optional="enabled" inherit_id="website_membership.index"> <xpath expr="//div[@id='left_column']/ul[last()]" position="after"> <ul class="nav nav-pills nav-stacked mt16"> <li class="nav-header"><h3>Location</h3></li> @@ -101,7 +101,7 @@ <!-- Option: index: Left Google Map --> <template id="opt_index_google_map" name="Left World Map" - inherit_option_id="website_membership.index" inherit_id="website_membership.index"> + optional="enabled" inherit_id="website_membership.index"> <xpath expr="//div[@id='left_column']/ul[1]" position="before"> <ul class="nav nav-pills nav-stacked mt16"> <li class="nav-header"><h3>World Map</h3></li> diff --git a/addons/website_quote/views/website_quotation.xml b/addons/website_quote/views/website_quotation.xml index 04d3eadb8c2f9c8f113d6371bfa74811d80d19a8..0415e2401ad1b1afb468b0ca7421cca8c448c331 100644 --- a/addons/website_quote/views/website_quotation.xml +++ b/addons/website_quote/views/website_quotation.xml @@ -92,7 +92,7 @@ </section> </template> - <template id="change_quantity" inherit_option_id="website_quote.pricing" name="Change Quantity"> + <template id="change_quantity" inherit_id="website_quote.pricing" optional="disabled" name="Change Quantity"> <xpath expr="//div[@id='quote_qty']" position="replace"> <div class="input-group"> <span class="input-group-addon hidden-print"> @@ -130,7 +130,7 @@ </template> <!-- Options:Quotation Chatter: user can reply --> - <template id="opt_quotation_chatter_post_complete_comment" name="Allow Comments" inherit_option_id="website_quote.chatter" inherit_id="website_quote.chatter"> + <template id="opt_quotation_chatter_post_complete_comment" name="Allow Comments" optional="enabled" inherit_id="website_quote.chatter"> <xpath expr="//h1" position="after"> <section class="mb32 css_editable_mode_hidden hidden-print"> <form id="comment" t-attf-action="/quote/#{quotation.id}/#{quotation.access_token}/post" method="POST"> @@ -388,7 +388,7 @@ </template> <!-- Options:Quotation Signature --> - <template id="opt_quotation_signature" name="Ask Signature" inherit_option_id="website_quote.so_quotation" inherit_id="website_quote.so_quotation"> + <template id="opt_quotation_signature" name="Ask Signature" optional="enabled" inherit_id="website_quote.so_quotation"> <xpath expr="//div[@id='sign-dialog']" position="inside"> <div class="panel panel-default mt16 mb0" id="drawsign"> <div class="panel-heading"> diff --git a/addons/website_sale/views/templates.xml b/addons/website_sale/views/templates.xml index 495e540c57ab1d2942f2e1f40c39cf38f4847dd6..0c69ece50cc5a480ac8130bb89bf69339193cc85 100644 --- a/addons/website_sale/views/templates.xml +++ b/addons/website_sale/views/templates.xml @@ -85,7 +85,7 @@ </div> </template> -<template id="products_description" inherit_option_id="website_sale.products_item" name="Product Description"> +<template id="products_description" inherit_id="website_sale.products_item" optional="disabled" name="Product Description"> <xpath expr="//div[@class='product_price']" position="before"> <div class="text-info oe_subdescription" contenteditable="false"> <div itemprop="description" t-field="product.description_sale"></div> @@ -93,7 +93,7 @@ </xpath> </template> -<template id="products_add_to_cart" inherit_option_id="website_sale.products_item" name="Add to Cart"> +<template id="products_add_to_cart" inherit_id="website_sale.products_item" optional="disabled" name="Add to Cart"> <xpath expr="//div[@class='product_price']" position="inside"> <form action="/shop/cart/update" method="post" style="display: inline-block;"> <input name="product_id" t-att-value="product.product_variant_ids[0].id" type="hidden"/> @@ -246,7 +246,7 @@ </li> </template> -<template id="products_categories" inherit_option_id="website_sale.products" name="Product Categories"> +<template id="products_categories" inherit_id="website_sale.products" optional="disabled" name="Product Categories"> <xpath expr="//div[@id='products_grid_before']" position="inside"> <ul class="nav nav-pills nav-stacked mt16"> <li t-att-class=" '' if category else 'active' "><a t-att-href="keep('/shop',category=0)">All Products</a></li> @@ -263,7 +263,7 @@ </xpath> </template> -<template id="products_attributes" inherit_option_id="website_sale.products" name="Product Attribute's Filters" groups="product.group_product_attributes"> +<template id="products_attributes" inherit_id="website_sale.products" optional="disabled" name="Product Attribute's Filters" groups="product.group_product_attributes"> <xpath expr="//div[@id='products_grid_before']" position="inside"> <form t-att-action="keep('shop',attrib=0)" class="attributes" method="get"> <ul class="nav nav-pills nav-stacked mt16"> @@ -293,7 +293,7 @@ </xpath> </template> -<template id="products_list_view" inherit_option_id="website_sale.products" name="List View"> +<template id="products_list_view" inherit_id="website_sale.products" optional="disabled" name="List View"> <xpath expr="//div[@id='products_grid']//table" position="replace"> <t t-foreach="products" t-as="product"> <div class="oe_product oe_list oe_product_cart" t-att-data-publish="product.website_published and 'on' or 'off'"> @@ -389,7 +389,7 @@ </t> </template> -<template id="recommended_products" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Alternative Products"> +<template id="recommended_products" inherit_id="website_sale.product" optional="enabled" name="Alternative Products"> <xpath expr="//div[@id='product_full_description']" position="after"> <div class="container mt32" t-if="product.alternative_product_ids"> <h3>Suggested alternatives:</h3> @@ -411,7 +411,7 @@ </xpath> </template> -<template id="product_attributes" inherit_id="website_sale.product" inherit_option_id="website_sale.product" name="Product attributes" groups="product.group_product_attributes"> +<template id="product_attributes" inherit_id="website_sale.product" optional="enabled" name="Product attributes" groups="product.group_product_attributes"> <xpath expr="//p[@t-field='product.description_sale']" position="after"> <hr t-if="product.attribute_lines"/> <p class="text-muted"> @@ -422,7 +422,7 @@ </xpath> </template> -<template id="product_comment" inherit_option_id="website_sale.product" name="Discussion"> +<template id="product_comment" inherit_id="website_sale.product" optional="disabled" name="Discussion"> <xpath expr="//div[@t-field='product.website_description']" position="after"> <hr class="mb32"/> <section class="container"> @@ -588,7 +588,7 @@ </t> </template> -<template id="suggested_products_list" inherit_id="website_sale.cart" inherit_option_id="website_sale.cart" name="Suggested Products in my cart"> +<template id="suggested_products_list" inherit_id="website_sale.cart" optional="enabled" name="Suggested Products in my cart"> <xpath expr="//table[@id='cart_products']" position="after"> <table t-if="suggested_products" class='table table-striped table-condensed'> <colgroup> @@ -644,13 +644,13 @@ </xpath> </template> -<template id="continue_shopping" inherit_id="website_sale.cart" inherit_option_id="website_sale.cart" name="Continue Shopping Button"> +<template id="continue_shopping" inherit_id="website_sale.cart" optional="enabled" name="Continue Shopping Button"> <xpath expr="//a[@href='/shop/checkout']" position="before"> <a href="/shop" class="btn btn-default mb32"><span class="fa fa-long-arrow-left"/> Continue Shopping</a> </xpath> </template> -<template id="reduction_code" inherit_option_id="website_sale.cart" name="Reduction Code"> +<template id="reduction_code" inherit_id="website_sale.cart" optional="disabled" name="Reduction Code"> <xpath expr="//div[@id='right_column']" position="inside"> <h4>Coupon Code</h4> <p> diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py index fc0edc24676cc497aedfd853ef860836ef5f24f3..aab5044d5b7bea65b1b102e77bb8ee467f91945d 100644 --- a/openerp/addons/base/ir/ir_ui_view.py +++ b/openerp/addons/base/ir/ir_ui_view.py @@ -155,9 +155,21 @@ class view(osv.osv): (<xpath/>) are applied, and the result is used as if it were this view's actual arch. """), + 'application': fields.selection([ + ('always', "Always applied"), + ('enabled', "Optional, enabled"), + ('disabled', "Optional, disabled"), + ], + required=True, string="Application status", + help="""If this view is inherited, +* if always, the view always extends its parent +* if enabled, the view currently extends its parent but can be disabled +* if disabled, the view currently does not extend its parent but can be enabled + """), } _defaults = { 'mode': 'primary', + 'application': 'always', 'priority': 16, } _order = "priority,name" @@ -256,6 +268,14 @@ class view(osv.osv): if custom_view_ids: self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids) + if vals.get('application') == 'disabled': + from_always = self.search( + cr, uid, [('id', 'in', ids), ('application', '=', 'always')], context=context) + if from_always: + raise ValueError( + "Can't disable views %s marked as always applied" % ( + ', '.join(map(str, from_always)))) + self.read_template.clear_cache(self) ret = super(view, self).write( cr, uid, ids, @@ -263,6 +283,21 @@ class view(osv.osv): context) return ret + def toggle(self, cr, uid, ids, context=None): + """ Switches between enabled and disabled application statuses + """ + for view in self.browse(cr, uid, ids, context=context): + if view.application == 'enabled': + view.write({'application': 'disabled'}) + elif view.application == 'disabled': + view.write({'application': 'enabled'}) + else: + raise ValueError(_("Can't toggle view %d with application %r") % ( + view.id, + view.application, + )) + + def copy(self, cr, uid, id, default=None, context=None): if not default: default = {} @@ -315,6 +350,7 @@ class view(osv.osv): ['inherit_id', '=', view_id], ['model', '=', model], ['mode', '=', 'extension'], + ['application', 'in', ['always', 'enabled']], ] if self.pool._init: # Module init currently in progress, only consider views from diff --git a/openerp/addons/base/tests/test_views.py b/openerp/addons/base/tests/test_views.py index 07cd4715b83ec9809339ffef4875d82d479836e7..9167b65a70fb3ee5918732b9a5306a5171e6daff 100644 --- a/openerp/addons/base/tests/test_views.py +++ b/openerp/addons/base/tests/test_views.py @@ -25,6 +25,13 @@ class ViewCase(common.TransactionCase): def create(self, value, context=None): return self.Views.create(self.cr, self.uid, value, context=context) + def read_combined(self, id): + return self.Views.read_combined( + self.cr, self.uid, + id, ['arch'], + context={'check_view_ids': self.Views.search(self.cr, self.uid, [])} + ) + def assertTreesEqual(self, n1, n2, msg=None): self.assertEqual(n1.tag, n2.tag, msg) self.assertEqual((n1.text or '').strip(), (n2.text or '').strip(), msg) @@ -632,6 +639,7 @@ class test_views(ViewCase): """Insert view into database via a query to passtrough validation""" kw.pop('id', None) kw.setdefault('mode', 'extension' if kw.get('inherit_id') else 'primary') + kw.setdefault('application', 'always') keys = sorted(kw.keys()) fields = ','.join('"%s"' % (k.replace('"', r'\"'),) for k in keys) @@ -1012,13 +1020,6 @@ class TestViewCombined(ViewCase): 'arch': '<xpath expr="//a1" position="after"><d1/></xpath>' }) - def read_combined(self, id): - return self.Views.read_combined( - self.cr, self.uid, - id, ['arch'], - context={'check_view_ids': self.Views.search(self.cr, self.uid, [])} - ) - def test_basic_read(self): arch = self.read_combined(self.a1)['arch'] self.assertEqual( @@ -1076,6 +1077,94 @@ class TestViewCombined(ViewCase): E.a2(), ), arch) +class TestOptionalViews(ViewCase): + """ + Tests ability to enable/disable inherited views, formerly known as + inherit_option_id + """ + + def setUp(self): + super(TestOptionalViews, self).setUp() + self.v0 = self.create({ + 'model': 'a', + 'arch': '<qweb><base/></qweb>', + }) + self.v1 = self.create({ + 'model': 'a', + 'inherit_id': self.v0, + 'application': 'always', + 'priority': 10, + 'arch': '<xpath expr="//base" position="after"><v1/></xpath>', + }) + self.v2 = self.create({ + 'model': 'a', + 'inherit_id': self.v0, + 'application': 'enabled', + 'priority': 9, + 'arch': '<xpath expr="//base" position="after"><v2/></xpath>', + }) + self.v3 = self.create({ + 'model': 'a', + 'inherit_id': self.v0, + 'application': 'disabled', + 'priority': 8, + 'arch': '<xpath expr="//base" position="after"><v3/></xpath>' + }) + + def test_applied(self): + """ mandatory and enabled views should be applied + """ + arch = self.read_combined(self.v0)['arch'] + self.assertEqual( + ET.fromstring(arch), + E.qweb( + E.base(), + E.v1(), + E.v2(), + ) + ) + + def test_applied_state_toggle(self): + """ Change application states of v2 and v3, check that the results + are as expected + """ + self.browse(self.v2).write({'application': 'disabled'}) + arch = self.read_combined(self.v0)['arch'] + self.assertEqual( + ET.fromstring(arch), + E.qweb( + E.base(), + E.v1(), + ) + ) + + self.browse(self.v3).write({'application': 'enabled'}) + arch = self.read_combined(self.v0)['arch'] + self.assertEqual( + ET.fromstring(arch), + E.qweb( + E.base(), + E.v1(), + E.v3(), + ) + ) + + self.browse(self.v2).write({'application': 'enabled'}) + arch = self.read_combined(self.v0)['arch'] + self.assertEqual( + ET.fromstring(arch), + E.qweb( + E.base(), + E.v1(), + E.v2(), + E.v3(), + ) + ) + + def test_mandatory_no_disabled(self): + with self.assertRaises(Exception): + self.browse(self.v1).write({'application': 'disabled'}) + class TestXPathExtentions(common.BaseCase): def test_hasclass(self): tree = E.node( diff --git a/openerp/import_xml.rng b/openerp/import_xml.rng index 8584267a2451e5b860b0eb10aada8e402dc446af..7f2067f3c365c96cdeeb36d3e2512cd18968fc6a 100644 --- a/openerp/import_xml.rng +++ b/openerp/import_xml.rng @@ -225,8 +225,15 @@ </rng:attribute> </rng:optional> </rng:optional> - <rng:optional><rng:attribute name="inherit_option_id"/></rng:optional> <rng:optional><rng:attribute name="groups"/></rng:optional> + <rng:optional> + <rng:attribute name="optional"> + <rng:choice> + <rng:value>enabled</rng:value> + <rng:value>disabled</rng:value> + </rng:choice> + </rng:attribute> + </rng:optional> </rng:group> <rng:optional> <rng:attribute name="page"><rng:value>True</rng:value></rng:attribute> diff --git a/openerp/tools/convert.py b/openerp/tools/convert.py index 8993002b1ece02ceb0ba63d72e5e9bc3ffdf9eb0..224bed8c715fd949806f4fc0ef4bf9787f47e40c 100644 --- a/openerp/tools/convert.py +++ b/openerp/tools/convert.py @@ -866,7 +866,7 @@ form: module.record_id""" % (xml_id,) if '.' not in full_tpl_id: full_tpl_id = '%s.%s' % (self.module, tpl_id) # set the full template name for qweb <module>.<id> - if not (el.get('inherit_id') or el.get('inherit_option_id')): + if not el.get('inherit_id'): el.set('t-name', full_tpl_id) el.tag = 't' else: @@ -889,9 +889,8 @@ form: module.record_id""" % (xml_id,) record.append(Field("qweb", name='type')) record.append(Field(el.get('priority', "16"), name='priority')) record.append(Field(el, name="arch", type="xml")) - for field_name in ('inherit_id','inherit_option_id'): - value = el.attrib.pop(field_name, None) - if value: record.append(Field(name=field_name, ref=value)) + if 'inherit_id' in el.attrib: + record.append(Field(name='inherit_id', ref=el.get('inherit_id'))) groups = el.attrib.pop('groups', None) if groups: grp_lst = map(lambda x: "ref('%s')" % x, groups.split(',')) @@ -900,6 +899,8 @@ form: module.record_id""" % (xml_id,) record.append(Field(name="page", eval="True")) if el.get('primary') == 'True': record.append(Field('primary', name='mode')) + if el.get('optional'): + record.append(Field(el.get('optional'), name='application')) return self._tag_record(cr, record, data_node)