Files
odoo_source/addons/website/models/ir_qweb.py
T
Olivier Dony e93b9aa271 [FIX] website: restore CDN for lazy assets
The CDN implementation for resources works by matching well-know attributes
(`href`, `src`, `action`) that hold URLs matching the CDN filters and injects
the CDN prefix. However 13.0 introduced lazy loading for assets in #32181,
so the attributes are now prefixed with `data-` and replaced at runtime.

This PR updates the tag matching in order to cover both variants of
attribute names.

closes odoo/odoo#54156

X-original-commit: 6d4b5fcd11e96fd170d8df1ed27be2a8cea26e8b
Signed-off-by: Toufik Benjaa (tbe) <tbe@odoo.com>
2020-07-06 16:02:04 +00:00

83 lines
3.1 KiB
Python

# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import re
from collections import OrderedDict
from odoo import models
from odoo.http import request
from odoo.addons.base.models.assetsbundle import AssetsBundle
from odoo.addons.http_routing.models.ir_http import url_for
from odoo.osv import expression
from odoo.addons.website.models import ir_http
from odoo.tools import html_escape as escape
re_background_image = re.compile(r"(background-image\s*:\s*url\(\s*['\"]?\s*)([^)'\"]+)")
class AssetsBundleMultiWebsite(AssetsBundle):
def _get_asset_url_values(self, id, unique, extra, name, sep, type):
website_id = self.env.context.get('website_id')
website_id_path = website_id and ('%s/' % website_id) or ''
extra = website_id_path + extra
res = super(AssetsBundleMultiWebsite, self)._get_asset_url_values(id, unique, extra, name, sep, type)
return res
def _get_assets_domain_for_already_processed_css(self, assets):
res = super(AssetsBundleMultiWebsite, self)._get_assets_domain_for_already_processed_css(assets)
current_website = self.env['website'].get_current_website(fallback=False)
res = expression.AND([res, current_website.website_domain()])
return res
class QWeb(models.AbstractModel):
""" QWeb object for rendering stuff in the website context """
_inherit = 'ir.qweb'
URL_ATTRS = {
'form': 'action',
'a': 'href',
'link': 'href',
'script': 'src',
'img': 'src',
}
def get_asset_bundle(self, xmlid, files, env=None):
return AssetsBundleMultiWebsite(xmlid, files, env=env)
def _post_processing_att(self, tagName, atts, options):
if atts.get('data-no-post-process'):
return atts
atts = super(QWeb, self)._post_processing_att(tagName, atts, options)
if options.get('inherit_branding') or options.get('rendering_bundle') or \
options.get('edit_translations') or options.get('debug') or (request and request.session.debug):
return atts
website = ir_http.get_request_website()
if not website and options.get('website_id'):
website = self.env['website'].browse(options['website_id'])
if not website:
return atts
name = self.URL_ATTRS.get(tagName)
if request and name and name in atts:
atts[name] = url_for(atts[name])
if not website.cdn_activated:
return atts
data_name = f'data-{name}'
if name and (name in atts or data_name in atts):
atts = OrderedDict(atts)
if name in atts:
atts[name] = website.get_cdn_url(atts[name])
if data_name in atts:
atts[data_name] = website.get_cdn_url(atts[data_name])
if isinstance(atts.get('style'), str) and 'background-image' in atts['style']:
atts = OrderedDict(atts)
atts['style'] = re_background_image.sub(lambda m: '%s%s' % (m.group(1), website.get_cdn_url(m.group(2))), atts['style'])
return atts