def get_tg(self, context): """If an object is created via portal factory we don't get a id, we have to wait till the object is really created. TODO: a better check if we are in the portal factory! """ try: context_id = ITG(context) # We must ensure that this case can't happen, any object translatable # will have an UUID (in any case we can be at the portal factory!) except TypeError: addAttributeTG(context, None) context.reindexObject(idxs=['TranslationGroup']) context_id = ITG(context) return context_id
def test_languages_untranslated_by_closest(self): # Define selector policy self.registry = getUtility(IRegistry) self.settings = self.registry.forInterface(IMultiLanguagePolicies) self.settings.selector_lookup_translations_policy = 'closest' wftool = getToolByName(self.portal, "portal_workflow") a_ca = createContentInContainer( self.portal['ca'], 'Document', title=u"Test document") a_ca.setLanguage('ca') wftool.doActionFor(a_ca, 'publish') view = selector_view(a_ca, self.request) view.tg = ITG(a_ca) # Check that the 'original' language gets the created document view.lang = 'ca' url = view.getClosestDestination() self.assertEqual(url, a_ca.absolute_url()) # Check that untranslated languages get the nearest translated parent view.lang = 'es' url = view.getClosestDestination() self.assertEqual(url, self.portal['es'].absolute_url()) view.lang = 'en' url = view.getClosestDestination() self.assertEqual(url, self.portal['en'].absolute_url()) # Check that translating content updates the closest destination a_es = api.translate(a_ca, 'es') view.lang = 'es' url = view.getClosestDestination() self.assertEqual(url, a_es.absolute_url())
def traverse(self, name, ignored): # Populate translation info self.info['target_language'] = ILanguage(self.context).get_language() catalog = getToolByName(self.context, 'portal_catalog') # Search source object using unrestricted API, # because user may be anonymous during traverse. brains = catalog.unrestrictedSearchResults(UID=name) if len(brains) != 1: raise TraversalError(self.context, name) source = brains[0]._unrestrictedGetObject() self.info['source_language'] = ILanguage(source).get_language() self.info['portal_type'] = source.portal_type self.info['tg'] = ITG(source) # If source has already been translated to this language, just redirect for brain in catalog.unrestrictedSearchResults( TranslationGroup=self.info['tg'], Language=self.info['target_language']): self.request.response.redirect(brain.getURL()) return u'' # XXX: register this adapter on dx container and a second one for AT if not IDexterityContent.providedBy(source): # we are not on DX content, assume AT baseUrl = self.context.absolute_url() url = '%s/@@add_at_translation?type=%s' % (baseUrl, name) return self.request.response.redirect(url) # set the self.context to the place where it should be stored if not IFolderish.providedBy(self.context): self.context = self.context.__parent__ # get the type information ttool = getToolByName(self.context, 'portal_types') ti = ttool.getTypeInfo(self.info['portal_type']) if ti is None: logger.error('No type information found for {0}'.format( self.info['portal_type'])) raise TraversalError(self.context, name) registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema) if not settings.redirect_babel_view: add_view = None else: add_view = queryMultiAdapter((self.context, self.request, ti), name='babel_view') if add_view is None: add_view = queryMultiAdapter((self.context, self.request, ti)) if add_view is not None: raise TraversalError(self.context, name) add_view.__name__ = ti.factory return add_view.__of__(self.context)
def get_translation_group(content): """Get the translation group. :param content: Content object which is part of the translation group. :type content: Content object :returns: UID string identifier of the translation group :raises: ValueError """ tg = ITG(content) if tg is None: raise ValueError('No translation group found.') return tg
def test_set_language_is_present(self): """ test the presence of set_language parameter in the urls created in the language selector""" self.settings.set_cookie_always = False self.selector_viewlet = LanguageSelectorViewlet( self.portal['en'], self.request, None, None ) self.selector_viewlet.update() selector_languages = self.selector_viewlet.languages() tg = ITG(self.portal['en']) self.assertListEqual( selector_languages, [ { 'code': u'en', u'flag': u'/++resource++country-flags/gb.gif', u'name': u'English', u'native': u'English', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal.absolute_url(), 'tg': tg, 'lang': 'en', 'query': '?set_language=en', }, 'selected': True, 'translated': True, }, { 'code': u'ca', u'flag': u'/++resource++language-flags/ca.gif', u'name': u'Catalan', u'native': u'Catal\xe0', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal.absolute_url(), 'tg': tg, 'lang': 'ca', 'query': '?set_language=ca', }, 'selected': False, 'translated': True, }, { 'code': u'es', u'flag': u'/++resource++country-flags/es.gif', u'name': u'Spanish', u'native': u'Espa\xf1ol', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal.absolute_url(), 'tg': tg, 'lang': 'es', 'query': '?set_language=es', }, 'selected': False, 'translated': True, }, ], )
def assertFullyTranslatedPages(self): a = createContentInContainer( self.portal['en'], 'Document', title=u"Test document" ) a_ca = api.translate(a, 'ca') a_ca.setTitle(u"Test Document (CA)") a_es = api.translate(a, 'es') a_es.setTitle(u"Test Document (ES)") wftool = getToolByName(self.portal, 'portal_workflow') wftool.doActionFor(a, 'publish') wftool.doActionFor(a_ca, 'publish') wftool.doActionFor(a_es, 'publish') notify(ObjectModifiedEvent(a)) notify(ObjectModifiedEvent(a_ca)) notify(ObjectModifiedEvent(a_es)) selector_viewlet = LanguageSelectorViewlet(a, self.request, None, None) selector_viewlet.update() selector_viewlet_languages = selector_viewlet.languages() self.assertEqual( selector_viewlet_languages, [ { 'code': u'en', u'flag': u'/++resource++country-flags/gb.gif', u'name': u'English', u'native': u'English', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal_url, 'tg': ITG(a), 'lang': 'en', 'query': '?set_language=en', }, 'selected': True, 'translated': True, }, { 'code': u'ca', u'flag': u'/++resource++language-flags/ca.gif', u'name': u'Catalan', u'native': u'Catal\xe0', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal_url, 'tg': ITG(a), 'lang': 'ca', 'query': '?set_language=ca', }, 'selected': False, 'translated': True, }, { 'code': u'es', u'flag': u'/++resource++country-flags/es.gif', u'name': u'Spanish', u'native': u'Espa\xf1ol', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal_url, 'tg': ITG(a), 'lang': 'es', 'query': '?set_language=es', }, 'selected': False, 'translated': True, }, ], ) transaction.commit() self.browser.open(selector_viewlet_languages[0]['url']) self.assertEqual( self.browser.url, a.absolute_url() + '?set_language=en' ) self.assertRegexpMatches(self.browser.contents, r"You\s*are here") self.browser.open(selector_viewlet_languages[1]['url']) self.assertEqual( self.browser.url, a_ca.absolute_url() + '?set_language=ca' ) self.assertIn('lang="ca"', self.browser.contents) self.browser.open(selector_viewlet_languages[2]['url']) self.assertEqual( self.browser.url, a_es.absolute_url() + '?set_language=es' ) self.assertIn('lang="es"', self.browser.contents)
def assertRootFolders(self): self.selector_viewlet = LanguageSelectorViewlet( self.portal['en'], self.request, None, None ) self.selector_viewlet.update() selector_languages = self.selector_viewlet.languages() tg = ITG(self.portal['en']) self.assertEqual( selector_languages, [ { 'code': u'en', u'flag': u'/++resource++country-flags/gb.gif', u'name': u'English', u'native': u'English', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal.absolute_url(), 'tg': tg, 'lang': 'en', 'query': '?set_language=en', }, 'selected': True, 'translated': True, }, { 'code': u'ca', u'flag': u'/++resource++language-flags/ca.gif', u'name': u'Catalan', u'native': u'Catal\xe0', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal.absolute_url(), 'tg': tg, 'lang': 'ca', 'query': '?set_language=ca', }, 'selected': False, 'translated': True, }, { 'code': u'es', u'flag': u'/++resource++country-flags/es.gif', u'name': u'Spanish', u'native': u'Espa\xf1ol', 'url': SELECTOR_VIEW_TEMPLATE % { 'url': self.portal.absolute_url(), 'tg': tg, 'lang': 'es', 'query': '?set_language=es', }, 'selected': False, 'translated': True, }, ], ) # Check EN self.browser.open(selector_languages[0]['url']) self.assertEqual( self.browser.url, self.portal['en'].absolute_url() + '?set_language=en', ) self.assertIn('lang="en"', self.browser.contents) self.assertRegexpMatches(self.browser.contents, r"You\s*are here") # Check CA self.browser.open(selector_languages[1]['url']) self.assertEqual( self.browser.url, self.portal.ca.absolute_url() + '?set_language=ca', ) self.assertIn('lang="ca"', self.browser.contents) # Check ES self.browser.open(selector_languages[2]['url']) self.assertEqual( self.browser.url, self.portal.es.absolute_url() + '?set_language=es', ) self.assertIn('lang="es"', self.browser.contents)
def __call__(self): return str(ITG(self.context, u""))
def itgIndexer(obj): return ITG(obj, None)
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form. """ # Settings site_url = getSite().absolute_url() language_tool = getToolByName(context, "portal_languages") show_flags = language_tool.showFlags try: lang_names = request.locale.displayNames.languages except AttributeError: lang_names = {} registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema, prefix="plone") if settings.redirect_babel_view: translation_view = 'babel_edit' else: translation_view = 'edit' # Content content = context content_url = context.absolute_url() content_language = ILanguage(content).get_language() content_translatable = not (content_language == LANGUAGE_INDEPENDENT or is_language_independent(content) or ILanguageRootFolder.providedBy(content)) content_translated = translated_languages(content) content_untranslated = untranslated_languages(content) content_translation_group = ITG(content, '') if not ITranslatable.providedBy(content): content = None # Folder when content is default page folder = aq_parent(context) if not is_default_page(folder, context): folder = None if folder and ITranslatable.providedBy(folder): # noqa folder_url = folder.absolute_url() folder_language = ILanguage(folder).get_language() folder_translatable = not (folder_language == LANGUAGE_INDEPENDENT or is_language_independent(folder) or ILanguageRootFolder.providedBy(folder)) folder_translated = translated_languages(folder) folder_untranslated = untranslated_languages(folder) folder_translation_group = ITG(folder, '') else: folder_url = '' folder_language = '' folder_translatable = False folder_translated = [] folder_untranslated = [] folder_translation_group = '' # Assets folder assets_folder_url = None assets_folder_title = None pc = getToolByName(getSite(), 'portal_catalog') results = pc.unrestrictedSearchResults( portal_type='LIF', Language=ILanguage(context).get_language()) for brain in results: assets_folder_url = brain.getURL() + '/folder_contents' assets_folder_title = safe_unicode(brain.Title) break # Menu items results = [] results_folder = [] results_content = [] if folder_translatable: # Folder translation view lang_name = lang_names.get(folder_language, folder_language) results_folder.append({ "title": _(u'edit_translation', default=u"Edit ${lang_name}", mapping={"lang_name": lang_name}), "description": _( u"description_babeledit_menu", default= u"Edit {lang_name} with the two-column translation view", # noqa mapping={"lang_name": lang_name}), "action": folder_url + "/" + translation_view, "selected": False, "icon": None, "extra": { "id": "_edit_folder_babel_edit", "separator": None, "class": "", }, "submenu": None, }) if folder and folder_untranslated and False: # disabled in favor of cut & paste # noqa # Set folder language results_folder.append({ "title": _(u'title_set_language', default=u"Change content language"), "description": _( u"description_set_language", default= u"Move the translation under another language folder" # noqa ), "action": folder_url + "/update_language", "selected": False, "icon": None, "extra": { "id": "_set_folder_language", "separator": None, "class": "" }, "submenu": None, }) if folder_translatable: for idx, lang in enumerate(folder_untranslated): lang_name = lang_names.get(lang.value, lang.title) lang_id = lang.value icon = show_flags and language_tool.getFlagForLanguageCode( lang_id) or None # noqa results_folder.append({ "title": _(u'create_translation', default=u"Create ${lang_name}", mapping={"lang_name": lang_name}), "description": _(u"description_translate_into", default=u"Translate into ${lang_name}", mapping={"lang_name": lang_name}), "action": "%s/@@create_translation?language=%s" % (folder_url, lang_id), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": { "id": "translate_folder_into_%s" % lang_id, "separator": None, "class": "contentmenuflags" }, "submenu": None, }) urls = translated_urls(folder) for lang in folder_translated: if lang.value not in urls.by_token: # omit if translation is not permitted to access. continue lang_name = lang_names.get(lang.value, lang.title) lang_id = lang.value icon = show_flags and language_tool.getFlagForLanguageCode( lang_id) or None # noqa results_folder.append({ "title": _(u'edit_translation', default=u"Edit ${lang_name}", mapping={"lang_name": lang_name}), "description": _( u"description_babeledit_menu", default= u"Edit {lang_name} with the two-column translation view", # noqa mapping={"lang_name": lang_name}), "action": (urls.getTerm(lang_id).title + "/" + translation_view), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": { "id": "babel_edit_%s" % lang_id, "separator": None, "class": "contentmenuflags" }, "submenu": None, }) # Manage folder translations results_folder.append({ "title": _(u"title_modify_translations", default=u"Manage translations"), "description": _(u"description_modify_translations", default=u"Add or delete translations"), "action": folder_url + "/modify_translations", "selected": False, "icon": None, "extra": { "id": "_modify_folder_translations", "separator": None, "class": "" }, "submenu": None, }) # Universal link if folder_translation_group: results_folder.append({ "title": _(u"universal_link", default=u"Universal link"), "description": _( u"description_universal_link", default= u"Universal link to the content in user's preferred language" # noqa ), "action": "%s/@@multilingual-universal-link/%s" % (site_url, folder_translation_group), "selected": False, "icon": None, "extra": { "id": "_universal_folder_link", "separator": None, "class": "" }, "submenu": None, }) if results_folder: # Folder translation separator results.append({ 'title': _(u'title_translate_current_folder', default=u'Folder translation'), 'description': '', 'action': None, 'selected': False, 'icon': None, 'extra': { 'id': 'translateFolderHeader', 'separator': 'actionSeparator', 'class': 'plone-toolbar-submenu-header' }, 'submenu': None, }) results.extend(results_folder) lang_name = lang_names.get(content_language, content_language) # Content language if content_untranslated and False: # disabled in favor of cut & paste results_content.append({ "title": _(u"title_set_language", default=u"Change content language"), "description": _( u"description_set_language", default= u"Move the translation under another language folder" # noqa ), "action": content_url + "/update_language", "selected": False, "icon": None, "extra": { "id": "_set_language", "separator": None, "class": "" }, "submenu": None, }) if content_translatable: # Content translation view results_content.append({ "title": _(u'edit_translation', default=u"Edit ${lang_name}", mapping={"lang_name": lang_name}), "description": _( u"description_babeledit_menu", default= u"Edit {lang_name} with the two-column translation view", # noqa mapping={"lang_name": lang_name}), "action": content_url + "/" + translation_view, "selected": False, "icon": None, "extra": { "id": "_edit_babel_edit", "separator": None, "class": "", }, "submenu": None, }) if content_translatable: for idx, lang in enumerate(content_untranslated): lang_name = lang_names.get(lang.value, lang.title) lang_id = lang.value icon = show_flags and language_tool.getFlagForLanguageCode( lang_id) or None # noqa results_content.append({ "title": _(u'create_translation', default=u"Create ${lang_name}", mapping={"lang_name": lang_name}), "description": _(u"description_translate_into", default=u"Translate into ${lang_name}", mapping={"lang_name": lang_name}), "action": "%s/@@create_translation?language=%s" % (content_url, lang_id), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": { "id": "translate_into_%s" % lang_id, "separator": None, "class": "contentmenuflags" }, "submenu": None, }) urls = translated_urls(content) for lang in content_translated: if lang.value not in urls.by_token: # omit if translation is not permitted to access. continue lang_name = lang_names.get(lang.value, lang.title) lang_id = lang.value icon = show_flags and language_tool.getFlagForLanguageCode( lang_id) or None # noqa results_content.append({ "title": _(u'edit_translation', default=u"Edit ${lang_name}", mapping={"lang_name": lang_name}), "description": _( u"description_babeledit_menu", default= u"Edit {lang_name} with the two-column translation view", # noqa mapping={"lang_name": lang_name}), "action": (urls.getTerm(lang_id).title + "/" + translation_view), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": { "id": "babel_edit_%s" % lang_id, "separator": None, "class": "contentmenuflags" }, "submenu": None, }) # Manage content translations results_content.append({ "title": _(u"title_modify_translations", default=u"Manage translations"), "description": _(u"description_modify_translations", default=u"Add or delete translations"), "action": content_url + "/modify_translations", "selected": False, "icon": None, "extra": { "id": "_modify_translations", "separator": None, "class": "" }, "submenu": None, }) # Universal link if content_translation_group: results_content.append({ "title": _(u"universal_link", default=u"Universal link"), "description": _( u"description_universal_link", default= u"Universal link to the content in user's preferred language" # noqa ), "action": "%s/@@multilingual-universal-link/%s" % (site_url, content_translation_group), "selected": False, "icon": None, "extra": { "id": "_universal_link", "separator": None, "class": "" }, "submenu": None, }) if results_folder and results_content: # Item translations separator results.append({ 'title': _(u'title_translate_current_item', default=u'Item translation'), 'description': '', 'action': None, 'selected': False, 'icon': None, 'extra': { 'id': 'translateItemHeader', 'separator': 'actionSeparator', 'class': '' }, 'submenu': None, }) results.extend(results_content) # Language independent assets folder if assets_folder_url: results.append({ "title": _(u"shared_folder", default=u"Open ${title} folder", mapping={"title": assets_folder_title}), "description": _(u"description_shared_folder", default=u"Open the language independent assets folder"), "action": assets_folder_url, "selected": False, "icon": None, "extra": { "id": "_shared_folder", "separator": results and 'actionSeparator' or None, "class": "" }, "submenu": None, }) # User preferred language root folder if not folder_translatable and not content_translatable: results.append({ "title": _(u"language_folder", default=u"Return to language folder"), "description": _(u"description_language_folder", default=u"Go to the user's browser preferred language " u"related folder"), "action": site_url + '/' + language_tool.getPreferredLanguage(), # noqa "selected": False, "icon": None, "extra": { "id": "_language_folder", "separator": ((results and not assets_folder_url) and 'actionSeparator' or None), "class": "" }, "submenu": None, }) return results