[IMP] base,web,website: asset bundle make url overridable

Allow to override the asset url generation to add in the path the website ID
and avoid continue invalidation cache and bad cache by browser.

Asset url is:
    "/web/content/{id}-{unique}/{extra}{name}{page}{type}"
with:
    id = attachment id
    unique = hash
    extra = allow to add custom params eg: website_id/ or rtl/
    name = filename
    page = used in css to split rules 4095 / file
    type = css|js

Co-authored-by: Derie Romain <rde@odoo.com>
Co-authored-by: Kersten Jérémy <jke@odoo.com>
This commit is contained in:
Jeremy Kersten
2018-08-13 20:16:34 +02:00
co-authored by Derie Romain
parent c0968e68ed
commit 853e13800f
3 changed files with 54 additions and 20 deletions
+1
View File
@@ -1002,6 +1002,7 @@ class Binary(http.Controller):
'/web/content/<int:id>/<string:filename>',
'/web/content/<int:id>-<string:unique>',
'/web/content/<int:id>-<string:unique>/<string:filename>',
'/web/content/<int:id>-<string:unique>/<path:extra>/<string:filename>',
'/web/content/<string:model>/<int:id>/<string:field>',
'/web/content/<string:model>/<int:id>/<string:field>/<string:filename>'], type='http', auth="public")
def content_common(self, xmlid=None, model='ir.attachment', id=None, field='datas',
+14
View File
@@ -5,11 +5,22 @@ from collections import OrderedDict
from odoo import models
from odoo.http import request
from odoo.addons.base.models.assetsbundle import AssetsBundle
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, page, 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, page, type)
return res
class QWeb(models.AbstractModel):
""" QWeb object for rendering stuff in the website context """
@@ -23,6 +34,9 @@ class QWeb(models.AbstractModel):
'img': 'src',
}
def get_asset_bundle(self, xmlid, files, remains=None, env=None):
return AssetsBundleMultiWebsite(xmlid, files, remains=remains, env=env)
def _post_processing_att(self, tagName, atts, options):
if atts.get('data-no-post-process'):
return atts
+39 -20
View File
@@ -198,6 +198,24 @@ class AssetsBundle(object):
check = u"%s%s" % (json.dumps(self.files, sort_keys=True), self.last_modified)
return hashlib.sha1(check.encode('utf-8')).hexdigest()
def _get_asset_template_url(self):
return "/web/content/{id}-{unique}/{extra}{name}{page}{type}" # name contains inc
def _get_asset_url_values(self, id, unique, extra, name, page, type): # extra can contain direction or/and website
return {
'id': id,
'unique': unique,
'extra': extra,
'name': name,
'page': page,
'type': type,
}
def get_asset_url(self, id='%', unique='%', extra='', name='%', page='%', type='%'):
return self._get_asset_template_url().format(
**self._get_asset_url_values(id=id, unique=unique, extra=extra, name=name, page=page, type=type)
)
def clean_attachments(self, type):
""" Takes care of deleting any outdated ir.attachment records associated to a bundle before
saving a fresh one.
@@ -213,13 +231,14 @@ class AssetsBundle(object):
must exclude the current bundle.
"""
ira = self.env['ir.attachment']
url = self.get_asset_url(
extra='%s' % ('rtl/' if type == 'css' and self.user_direction == 'rtl' else ''),
name=self.name,
type=type
)
domain = [
('url', '=like', '/web/content/%-%-{}/{}{}%.{}'.format( # The wilcards are id, version and pagination number (if any)
self.env.context.get('website_id'),
('rtl/' if type == 'css' and self.user_direction == 'rtl' else ''),
self.name,
type)),
'!', ('url', '=like', '/web/content/%-{}/%'.format(self.version))
('url', '=like', url),
'!', ('url', '=like', self.get_asset_url(unique=self.version))
]
# force bundle invalidation on other workers
@@ -235,14 +254,13 @@ class AssetsBundle(object):
multiple time the same bundle in our `to_html` function, we group our ir.attachment records
by file name and only return the one with the max id for each group.
"""
version = "%" if ignore_version else self.version
url_pattern = '/web/content/%-{}-{}/{}{}{}.{}'.format(
version,
self.env.context.get('website_id'),
('rtl/' if type == 'css' and self.user_direction == 'rtl' else ''),
self.name,
'.%' if type == 'css' else '',
type
unique = "%" if ignore_version else self.version
url_pattern = self.get_asset_url(
unique=unique,
extra='%s' % ('rtl/' if type == 'css' and self.user_direction == 'rtl' else ''),
name=self.name,
page='.%' if type == 'css' else '',
type='.%s' % type
)
self.env.cr.execute("""
SELECT max(id)
@@ -281,12 +299,13 @@ class AssetsBundle(object):
}
attachment = ira.sudo().create(values)
url = '/web/content/%s-%s-%s%s/%s' % (
attachment.id,
self.version,
self.env.context.get('website_id'),
('/rtl' if type == 'css' and self.user_direction == 'rtl' else ''),
fname
url = self.get_asset_url(
id=attachment.id,
unique=self.version,
extra='%s' % ('rtl/' if type == 'css' and self.user_direction == 'rtl' else ''),
name=fname,
page='', # included in fname
type='' # included in fname
)
values = {
'name': url,