class IrQWeb(models.AbstractModel, QWeb): _inherit = 'ir.qweb' @tools.conditional( # in non-xml-debug mode we want assets to be cached forever, and the admin can force a cache clear # by restarting the server after updating the source code (or using the "Clear server cache" in debug tools) 'xml' not in tools.config['dev_mode'], tools.ormcache('xmlid', 'options.get("lang", "en_US")', 'css', 'js', 'debug', 'async'), ) def _get_asset(self, xmlid, options, css=True, js=True, debug=False, async=False, values=None):
class IrQWeb(models.AbstractModel, QWeb): """ Base QWeb rendering engine * to customize ``t-field`` rendering, subclass ``ir.qweb.field`` and create new models called :samp:`ir.qweb.field.{widget}` Beware that if you need extensions or alterations which could be incompatible with other subsystems, you should create a local object inheriting from ``ir.qweb`` and customize that. """ _name = 'ir.qweb' @api.model def render(self, id_or_xml_id, values=None, **options): """ render(id_or_xml_id, values, **options) Render the template specified by the given name. :param id_or_xml_id: name or etree (see get_template) :param dict values: template values to be used for rendering :param options: used to compile the template (the dict available for the rendering is frozen) * ``load`` (function) overrides the load method * ``profile`` (float) profile the rendering (use astor lib) (filter profile line with time ms >= profile) """ for method in dir(self): if method.startswith('render_'): _logger.warning("Unused method '%s' is found in ir.qweb." % method) context = dict(self.env.context, dev_mode='qweb' in tools.config['dev_mode']) context.update(options) return super(IrQWeb, self).render(id_or_xml_id, values=values, **context) def default_values(self): """ attributes add to the values for each computed template """ default = super(IrQWeb, self).default_values() default.update( request=request, cache_assets=round(time() / 180), true=True, false=False ) # true and false added for backward compatibility to remove after v10 return default # assume cache will be invalidated by third party on write to ir.ui.view def _get_template_cache_keys(self): """ Return the list of context keys to use for caching ``_get_template``. """ return [ 'lang', 'inherit_branding', 'editable', 'translatable', 'edit_translations' ] # apply ormcache_context decorator unless in dev mode... @tools.conditional( 'xml' not in tools.config['dev_mode'], tools.ormcache( 'id_or_xml_id', 'tuple(map(options.get, self._get_template_cache_keys()))'), ) def compile(self, id_or_xml_id, options): return super(IrQWeb, self).compile(id_or_xml_id, options=options) def load(self, name, options): lang = options.get('lang', 'en_US') env = self.env if lang != env.context.get('lang'): env = env(context=dict(env.context, lang=lang)) template = env['ir.ui.view'].read_template(name) res_id = isinstance(name, (int, long)) and name or None if res_id: for node in etree.fromstring(template): if node.get('t-name'): return node elif res_id and node.tag == "t": node.set('t-name', str(res_id)) return node return template # order def _directives_eval_order(self): directives = super(IrQWeb, self)._directives_eval_order() directives.insert(directives.index('call'), 'lang') directives.insert(directives.index('field'), 'call-assets') return directives # compile directives def _compile_directive_lang(self, el, options): lang = el.attrib.pop('t-lang', 'en_US') if el.get('t-call-options'): el.set('t-call-options', el.get('t-call-options')[0:-1] + u', "lang": %s}' % lang) else: el.set('t-call-options', u'{"lang": %s}' % lang) return self._compile_node(el, options) def _compile_directive_call_assets(self, el, options): """ This special 't-call' tag can be used in order to aggregate/minify javascript and css assets""" if len(el): raise "t-call-assets cannot contain children nodes" # self._get_asset(xmlid, options, css=css, js=js, debug=values.get('debug'), async=async, values=values) return [ self._append( ast.Call( func=ast.Attribute(value=ast.Name(id='self', ctx=ast.Load()), attr='_get_asset', ctx=ast.Load()), args=[ ast.Str(el.get('t-call-assets')), ast.Name(id='options', ctx=ast.Load()), ], keywords=[ ast.keyword('css', self._get_attr_bool(el.get('t-css', True))), ast.keyword('js', self._get_attr_bool(el.get('t-js', True))), ast.keyword( 'debug', ast.Call(func=ast.Attribute(value=ast.Name( id='values', ctx=ast.Load()), attr='get', ctx=ast.Load()), args=[ast.Str('debug')], keywords=[], starargs=None, kwargs=None)), ast.keyword( 'async', self._get_attr_bool(el.get('async', False))), ast.keyword('values', ast.Name(id='values', ctx=ast.Load())), ], starargs=None, kwargs=None)) ] # for backward compatibility to remove after v10 def _compile_widget_options(self, el, directive_type): field_options = super(IrQWeb, self)._compile_widget_options( el, directive_type) if ('t-%s-options' % directive_type) in el.attrib: if tools.config['dev_mode']: _logger.warning( "Use new syntax t-options instead of t-%s-options" % directive_type) if not field_options: field_options = el.attrib.pop('t-%s-options' % directive_type) if field_options and 'monetary' in field_options: try: options = "{'widget': 'monetary'" for k, v in json.loads(field_options).iteritems(): print k, v if k in ('display_currency', 'from_currency'): options = "%s, '%s': %s" % (options, k, v) else: options = "%s, '%s': '%s'" % (options, k, v) options = "%s}" % options field_options = options _logger.warning( "Use new syntax for '%s' monetary widget t-options (python dict instead of deprecated JSON syntax)." % etree.tostring(el)) except ValueError: pass return field_options # end backward # method called by computing code @tools.conditional( # in non-xml-debug mode we want assets to be cached forever, and the admin can force a cache clear # by restarting the server after updating the source code (or using the "Clear server cache" in debug tools) 'xml' not in tools.config['dev_mode'], tools.ormcache('xmlid', 'options.get("lang", "en_US")', 'css', 'js', 'debug', 'async'), ) def _get_asset(self, xmlid, options, css=True, js=True, debug=False, async=False, values=None):