[FIX] ir.ui.view: qweb translations: allow looking up translation in parent template

- Translations lookup normally uses the namespace of the current
QWeb template, after merging all inherited views.
But when a QWeb template is "cloned" by a child view using
inheritance with `primary` mode, the translations are more
likely to exist for the original (parent) template, and would not
be found when using only the "child" namespace.
This patch adds support for looking up each translation
also in the parent namespace in this case, if none was found
for the child template in the first place.

- ir.translation's _get_source() now supports a list of res_id
to search for, in addition to a single res_id

- Also moved the logic of routes /website/customize_template_get
and /website/get_view_translations to the ir.ui.view model where
it belongs.

opw: 615241

Closes #5325
This commit is contained in:
Goffin Simon 2015-02-13 13:30:53 +01:00 committed by Goffin Simon
parent 46186f54eb
commit cbb51610ee
4 changed files with 72 additions and 49 deletions

View File

@ -227,54 +227,16 @@ class Website(openerp.addons.web.controllers.main.Home):
@http.route('/website/customize_template_get', type='json', auth='user', website=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')
return request.registry["ir.ui.view"].customize_template_get(
request.cr, request.uid, xml_id, full=full, context=request.context)
user = request.registry['res.users']\
.browse(request.cr, request.uid, request.uid, request.context)
user_groups = set(user.groups_id)
views = request.registry["ir.ui.view"]\
._views_get(request.cr, request.uid, xml_id, context=dict(request.context or {}, active_test=False))
done = set()
result = []
for v in views:
if not user_groups.issuperset(v.groups_id):
continue
if full or (v.customize_show and v.inherit_id.id != view_theme_id):
if v.inherit_id not in done:
result.append({
'name': v.inherit_id.name,
'id': v.id,
'xml_id': v.xml_id,
'inherit_id': v.inherit_id.id,
'header': True,
'active': False
})
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.active,
})
return result
@http.route('/website/get_view_translations', type='json', auth='public', website=True)
def get_view_translations(self, xml_id, lang=None):
lang = lang or request.context.get('lang')
views = self.customize_template_get(xml_id, full=True)
views_ids = [view.get('id') for view in views if view.get('active')]
domain = [('type', '=', 'view'), ('res_id', 'in', views_ids), ('lang', '=', lang)]
irt = request.registry.get('ir.translation')
return irt.search_read(request.cr, request.uid, domain, ['id', 'res_id', 'value','state','gengo_translation'], context=request.context)
return request.registry["ir.ui.view"].get_view_translations(
request.cr, request.uid, xml_id, lang=lang, context=request.context)
@http.route('/website/set_translations', type='json', auth='public', website=True)
def set_translations(self, data, lang):

View File

@ -215,3 +215,47 @@ class view(osv.osv):
if view.model_data_id:
view.model_data_id.write({'noupdate': True})
def customize_template_get(self, cr, uid, xml_id, full=False, bundles=False , context=None):
""" Get inherit view's informations of the template ``key``. By default, only
returns ``customize_show`` templates (which can be active or not), if
``full=True`` returns inherit view's informations of the template ``key``.
``bundles=True`` returns also the asset bundles
"""
imd = request.registry['ir.model.data']
view_model, view_theme_id = imd.get_object_reference(cr, uid, 'website', 'theme')
user = request.registry['res.users'].browse(cr, uid, uid, context)
user_groups = set(user.groups_id)
views = self._views_get(cr, uid, xml_id, context=dict(context or {}, active_test=False))
done = set()
result = []
for v in views:
if not user_groups.issuperset(v.groups_id):
continue
if full or (v.customize_show and v.inherit_id.id != view_theme_id):
if v.inherit_id not in done:
result.append({
'name': v.inherit_id.name,
'id': v.id,
'xml_id': v.xml_id,
'inherit_id': v.inherit_id.id,
'header': True,
'active': False
})
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.active,
})
return result
def get_view_translations(self, cr, uid, xml_id, lang, field=['id', 'res_id', 'value', 'state', 'gengo_translation'], context=None):
views = self.customize_template_get(cr, uid, xml_id, full=True, context=context)
views_ids = [view.get('id') for view in views if view.get('active')]
domain = [('type', '=', 'view'), ('res_id', 'in', views_ids), ('lang', '=', lang)]
irt = request.registry.get('ir.translation')
return irt.search_read(cr, uid, domain, field, context=context)

View File

@ -310,7 +310,11 @@ class ir_translation(osv.osv):
AND src=%s"""
params = (lang or '', types, tools.ustr(source))
if res_id:
query += " AND res_id=%s"
if isinstance(res_id, (int, long)):
res_id = (res_id,)
else:
res_id = tuple(res_id)
query += " AND res_id in %s"
params += (res_id,)
if name:
query += " AND name=%s"
@ -337,7 +341,7 @@ class ir_translation(osv.osv):
:param types: single string defining type of term to translate (see ``type`` field on ir.translation), or sequence of allowed types (strings)
:param lang: language code of the desired translation
:param source: optional source term to translate (should be unicode)
:param res_id: optional resource id to translate (if used, ``source`` should be set)
:param res_id: optional resource id or a list of ids to translate (if used, ``source`` should be set)
:rtype: unicode
:return: the request translation, or an empty unicode string if no translation was
found and `source` was not passed

View File

@ -940,10 +940,9 @@ class view(osv.osv):
for attr in node.attrib
)
def translate_qweb(self, cr, uid, id_, arch, lang, context=None):
def _translate_qweb(self, cr, uid, arch, translate_func, context=None):
# TODO: this should be moved in a place before inheritance is applied
# but process() is only called on fields_view_get()
Translations = self.pool['ir.translation']
h = HTMLParser.HTMLParser()
def get_trans(text):
if not text or not text.strip():
@ -951,7 +950,7 @@ class view(osv.osv):
text = h.unescape(text.strip())
if len(text) < 2 or (text.startswith('<!') and text.endswith('>')):
return None
return Translations._get_source(cr, uid, 'website', 'view', lang, text, id_)
return translate_func(text)
if type(arch) not in SKIPPED_ELEMENT_TYPES and arch.tag not in SKIPPED_ELEMENTS:
text = get_trans(arch.text)
@ -966,7 +965,21 @@ class view(osv.osv):
if attr:
arch.set(attr_name, attr)
for node in arch.iterchildren("*"):
self.translate_qweb(cr, uid, id_, node, lang, context)
self._translate_qweb(cr, uid, node, translate_func, context)
def translate_qweb(self, cr, uid, id_, arch, lang, context=None):
view_ids = []
view = self.browse(cr, uid, id_, context=context)
if view:
view_ids.append(view.id)
if view.mode == 'primary' and view.inherit_id.mode == 'primary':
# template is `cloned` from parent view
view_ids.append(view.inherit_id.id)
Translations = self.pool['ir.translation']
def translate_func(term):
trans = Translations._get_source(cr, uid, 'website', 'view', lang, term, view_ids)
return trans
self._translate_qweb(cr, uid, arch, translate_func, context=context)
return arch
@openerp.tools.ormcache()