Commit f14811fa authored by Jérome Perrin's avatar Jérome Perrin

content_translation: Also index translations from message catalogs

Now that we are able to search using content translation, we also want
to extend this so that columns like "group__title" can be searchable in listboxs,
but categories are usually translated with `erp5_content`, which was not indexed
in content_translation table.

Extend content translation indexing to also support translations coming from
Localizer catalog make this possible.

The only limitation I could think of is that categories will need to be reindexed
when the messages are modified in catalog.
parent aee8bcac
Pipeline #12175 failed with stage
in 0 seconds
...@@ -7,7 +7,8 @@ result = [] ...@@ -7,7 +7,8 @@ result = []
def upperCase(text): def upperCase(text):
return convertToUpperCase(text.replace('-', '_')) return convertToUpperCase(text.replace('-', '_'))
content_language_list = context.Localizer.get_languages() localizer = portal.Localizer
content_language_list = localizer.get_languages()
for document in document_list: for document in document_list:
portal_type = document.getPortalType() portal_type = document.getPortalType()
...@@ -23,19 +24,29 @@ for document in document_list: ...@@ -23,19 +24,29 @@ for document in document_list:
if original_method is not None: if original_method is not None:
original_text = original_method() original_text = original_method()
property_translation_domain = document.getProperty('%s_translation_domain' % property_name)
for content_language in content_language_list: for content_language in content_language_list:
method_name = 'get%s' % (upperCase('%s_translated_%s' % method_name = 'get%s' % (upperCase('%s_translated_%s' %
(content_language, property_name)),) (content_language, property_name)),)
translated_text = None translated_text = None
method = getattr(document, method_name, None) method = getattr(document, method_name, None)
if method is not None and document.getProperty('%s_translation_domain' % property_name) == 'content': if method is not None and property_translation_domain == 'content':
translated_text = method() translated_text = method()
else: elif property_translation_domain == 'content_translation':
translation_method = getattr(document, 'get%s' % upperCase('translated_%s' % property_name), None) translation_method = getattr(document, 'get%s' % upperCase('translated_%s' % property_name), None)
if original_text is not None and translation_method is not None: if original_text is not None and translation_method is not None:
temporary_translated_text = translation_method(language=content_language) temporary_translated_text = translation_method(language=content_language)
if original_text != temporary_translated_text: if original_text != temporary_translated_text:
translated_text = temporary_translated_text translated_text = temporary_translated_text
elif original_text:
temporary_translated_text = (localizer.translate(
domain=property_translation_domain,
msgid=original_text,
lang=content_language
) or original_text).encode('utf-8')
if original_text != temporary_translated_text:
translated_text = temporary_translated_text
temporary_result.append({'uid': uid, temporary_result.append({'uid': uid,
'property_name': property_name, 'property_name': property_name,
'content_language': content_language, 'content_language': content_language,
......
...@@ -3,10 +3,10 @@ from Products.ERP5Type.Cache import CachingMethod ...@@ -3,10 +3,10 @@ from Products.ERP5Type.Cache import CachingMethod
def getPortalTypeContentTranslationMapping(): def getPortalTypeContentTranslationMapping():
result = {} result = {}
for type_information in context.getPortalObject().portal_types.listTypeInfo(): for type_information in context.getPortalObject().portal_types.listTypeInfo():
content_translation_domain_property_name_list =\ for property_name, translation_domain in type_information.getPropertyTranslationDomainDict().items():
type_information.getContentTranslationDomainPropertyNameList() domain_name = translation_domain.getDomainName()
if content_translation_domain_property_name_list: if domain_name:
result[type_information.getId()] = content_translation_domain_property_name_list result.setdefault(type_information.getId(), []).append(property_name)
return result return result
getPortalTypeContentTranslationMapping = CachingMethod( getPortalTypeContentTranslationMapping = CachingMethod(
......
...@@ -113,7 +113,7 @@ class TestContentTranslation(ERP5TypeTestCase): ...@@ -113,7 +113,7 @@ class TestContentTranslation(ERP5TypeTestCase):
# Low level columns test. This behaviour is not guaranteed. I'm not sure # Low level columns test. This behaviour is not guaranteed. I'm not sure
# content_translation must be a search table - jerome # content_translation must be a search table - jerome
result5 = portal.portal_catalog(property_name='title') result5 = portal.portal_catalog(property_name='title')
self.assertEqual(len(result5), 2) self.assertGreaterEqual(len(result5), 2)
result6 = portal.portal_catalog(content_language='nob-read') result6 = portal.portal_catalog(content_language='nob-read')
self.assertEqual(len(result6), 2) self.assertEqual(len(result6), 2)
result7 = portal.portal_catalog(translated_text='XXX YYY') result7 = portal.portal_catalog(translated_text='XXX YYY')
......
...@@ -45,6 +45,7 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase): ...@@ -45,6 +45,7 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase):
# * title as "content translated properties" on Organisation # * title as "content translated properties" on Organisation
# * short_title as "content translated properties" on Organisation (because it contain a _, # * short_title as "content translated properties" on Organisation (because it contain a _,
# to make sure we are supporting properties with _) # to make sure we are supporting properties with _)
# * some "group" categories and their translations in erp5_content
# * two organisations # * two organisations
self.portal.portal_types.Organisation.setTranslationDomain( self.portal.portal_types.Organisation.setTranslationDomain(
prop_name='title', domain='content_translation') prop_name='title', domain='content_translation')
...@@ -56,10 +57,29 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase): ...@@ -56,10 +57,29 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase):
self.commit() self.commit()
self.portal.portal_caches.clearCacheFactory('erp5_content_long') self.portal.portal_caches.clearCacheFactory('erp5_content_long')
# translations for categories
message_catalog = self.portal.Localizer.erp5_content
message_catalog.add_language('fr')
message_catalog.add_language('ja')
message_catalog.gettext('Nexedi', add=True)
message_catalog.gettext('Another', add=True)
message_catalog.message_edit('Nexedi', 'fr', u'Catégorie Nexedi', '')
message_catalog.message_edit('Another', 'fr', u'Autre Catégorie', '')
message_catalog.message_edit('Nexedi', 'ja', u'ネクセディカテゴリー', '')
message_catalog.message_edit('Another', 'ja', u'別カテゴリー', '')
# categories (which will be translated using erp5_content)
group_base_category = self.portal.portal_categories.group
if 'nexedi' not in group_base_category.objectIds():
group_base_category.newContent(id='nexedi', title='Nexedi')
if 'another' not in group_base_category.objectIds():
group_base_category.newContent(id='another', title='Another')
self.organisation_nexedi = self.portal.organisation_module.newContent( self.organisation_nexedi = self.portal.organisation_module.newContent(
portal_type='Organisation', portal_type='Organisation',
title='Nexedi', title='Nexedi',
short_title='Nexedi SA', short_title='Nexedi SA',
group_value=group_base_category.nexedi,
) )
self.organisation_nexedi.setFrTranslatedTitle("Nexedi") self.organisation_nexedi.setFrTranslatedTitle("Nexedi")
self.organisation_nexedi.setFrTranslatedShortTitle("Nexedi Société Anonyme") self.organisation_nexedi.setFrTranslatedShortTitle("Nexedi Société Anonyme")
...@@ -68,6 +88,7 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase): ...@@ -68,6 +88,7 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase):
self.organisation_another = self.portal.organisation_module.newContent( self.organisation_another = self.portal.organisation_module.newContent(
portal_type='Organisation', portal_type='Organisation',
title='Another not translated Organisation', title='Another not translated Organisation',
group_value=group_base_category.another,
) )
self.tic() self.tic()
...@@ -209,3 +230,35 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase): ...@@ -209,3 +230,35 @@ class TestTranslatedRelatedKeys(ERP5TypeTestCase):
'Nexedi', 'Nexedi',
'ネクセディ', 'ネクセディ',
]) ])
def test_erp5_content_search_folder(self):
localizer = self.portal.Localizer
with mock.patch.object(
localizer,
'get_selected_language',
return_value='ja',
):
self.assertEqual(
[
x.getObject()
for x in self.portal.organisation_module.searchFolder(
uid=(
self.organisation_nexedi.getUid(),
self.organisation_another.getUid()),
group__translated__title='ネクセディカテゴリー')
], [self.organisation_nexedi])
with mock.patch.object(
localizer,
'get_selected_language',
return_value='fr',
):
self.assertEqual(
[
x.getObject()
for x in self.portal.organisation_module.searchFolder(
uid=(
self.organisation_nexedi.getUid(),
self.organisation_another.getUid()),
group__translated__title='Catégorie Nexedi')
], [self.organisation_nexedi])
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment