def test_moving_shared_content_to_lrf(self): # Create shared document createContentInContainer(self.portal, "LIF", title=u"Media", checkConstraints=False) createContentInContainer(self.portal.media, "Document", title=u"Test document") uuid = IUUID(self.portal.media["test-document"]) # Check that ghost is ghost self.assertTrue(is_language_independent(self.portal.ca.media["test-document"])) # Check is in the catalog brains = self.portal.portal_catalog.searchResults(UID=uuid) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), "/plone/media/test-document") brains = self.portal.portal_catalog.searchResults(UID="{0:s}-ca".format(uuid)) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), "/plone/ca/media/test-document") brains = self.portal.portal_catalog.searchResults(UID="{0:s}-es".format(uuid)) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), "/plone/es/media/test-document") # MOVE! moved = multilingualMoveObject(self.portal.ca.media["test-document"], "ca") # Check that the old and the new uuid are the same moved_uuid = IUUID(self.portal.ca["test-document"]) self.assertEqual(uuid, moved_uuid) self.assertFalse(is_language_independent(moved)) # Check portal_catalog is updated after move brains = self.portal.portal_catalog.searchResults(UID=uuid) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), "/plone/ca/test-document") brains = self.portal.portal_catalog.searchResults(UID="{0:s}-ca".format(uuid)) self.assertEqual(len(brains), 0) brains = self.portal.portal_catalog.searchResults(UID="{0:s}-es".format(uuid)) self.assertEqual(len(brains), 0) # Check which translations it have self.assertEqual(ITranslationManager(moved).get_translations(), {"ca": moved}) ITranslationManager(moved).add_translation("es") self.assertEqual( ITranslationManager(moved).get_translations(), {"ca": moved, "es": self.portal.es["test-document"]} ) # Check that ghost is no longer ghost self.assertFalse(is_language_independent(self.portal.es["test-document"]))
def unindex_language_independent(ob, event): """Un-index language independent object for other languages Language independent objects are indexed once for each language with different, language code post-fixed, UUID for each. When ever a language independent object is removed in some language, we must un-indexed all the other languages as well. XXX: Removing any language independent folder will unindex contents of all language independent folders. When that happens, catalog clear and rebuild would restore contenst for the other folders. """ if not is_language_independent(ob): return try: pc = getToolByName(ob, 'portal_catalog') except AttributeError: # When we are removing the site, there is no portal_catalog: return language_tool = getToolByName(ob, 'portal_languages') language_codes = language_tool.supported_langs uuid = IUUID(ob).split('-')[0] for code in language_codes: for brain in pc.unrestrictedSearchResults(UID=uuid + '-' + code): ob.unrestrictedTraverse(brain.getPath()).unindexObject() for brain in pc.unrestrictedSearchResults(UID=uuid): ob.unrestrictedTraverse(brain.getPath()).unindexObject()
def reindex_language_independent(ob, event): """Re-index language independent object for other languages Language independent objects are indexed once for each language with different, language code post-fixed, UUID for each. When ever a language independent object is modified in some language, it must be re-indexed for all the other languages as well. """ if not is_language_independent(ob): return pc = getToolByName(ob, 'portal_catalog') parent = aq_parent(ob) # Re-index objects just below the language independent folder if ILanguageIndependentFolder.providedBy(parent): brains = pc.unrestrictedSearchResults(portal_type='LIF') for brain in brains: lif = brain._unrestrictedGetObject() if lif != parent: lif[ob.id].indexObject() # Re-index objects deeper inside language independent folder else: language_tool = getToolByName(ob, 'portal_languages') language_codes = language_tool.supported_langs parent_uuid = IUUID(parent).split('-')[0] + '-' for code in language_codes: results = pc.unrestrictedSearchResults(UID=parent_uuid + code) # When we have results, parent has been indexed and we can reindex: for brain in results: tmp = ob.unrestrictedTraverse(brain.getPath() + '/' + ob.id) tmp.reindexObject()
def set_recursive_language(ob, language): """Set the language for this object and its children in a recursive manner """ if is_language_independent(ob): ILanguage(ob).set_language(None) elif ILanguage(ob).get_language() != language: ILanguage(ob).set_language(language) ITranslationManager(ob).update() reindex_object(ob) for child in (IFolderish.providedBy(ob) and ob.items() or ()): if ITranslatable.providedBy(child): set_recursive_language(child, language)
def untranslated_languages(context): language_tool = getToolByName(context, 'portal_languages') language_infos = language_tool.getAvailableLanguages() available_portal_languages = language_tool.supported_langs manager = ITranslationManager(context) translated_languages = manager.get_translated_languages() if is_language_independent(context): translated_languages = [] languages = [] for lang in available_portal_languages: if lang not in translated_languages: native = language_infos[lang].get('native', None) name = language_infos[lang].get('name', lang) languages.append( SimpleVocabulary.createTerm(lang, lang, native or name)) return SimpleVocabulary(languages)
def reindex_language_independent(ob, event): """Re-index language independent object for other languages Language independent objects are indexed once for each language with different, language code post-fixed, UUID for each. When ever a language independent object is modified in some language, it must be re-indexed for all the other languages as well. """ if not is_language_independent(ob): return if IObjectRemovedEvent.providedBy(event): return pc = getToolByName(ob, 'portal_catalog') parent = aq_parent(ob) # Re-index objects just below the language independent folder if ILanguageIndependentFolder.providedBy(parent): brains = pc.unrestrictedSearchResults(portal_type='LIF') for brain in brains: lif = brain._unrestrictedGetObject() if lif != parent: lif[ob.id].indexObject() # Re-index objects deeper inside language independent folder else: language_tool = getToolByName(ob, 'portal_languages') language_codes = language_tool.supported_langs parent_uuid = IUUID(parent).split('-')[0] + '-' for code in language_codes: results = pc.unrestrictedSearchResults(UID=parent_uuid + code) # When we have results, parent has been indexed and we can reindex: for brain in results: tmp = ob.unrestrictedTraverse(brain.getPath() + '/' + ob.id) tmp.reindexObject()
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form. """ try: lang_names = request.locale.displayNames.languages except AttributeError: lang_names = {} menu = [] url = context.absolute_url() lt = getToolByName(context, "portal_languages") site_url = getSite().absolute_url() showflags = lt.showFlags context_id = ITranslationManager(context).tg registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema, prefix="plone") edit_view = 'babel_edit' if settings.redirect_babel_view else 'edit' # In case is neutral language show set language menu only is_neutral_content = (ILanguage(context).get_language() == LANGUAGE_INDEPENDENT or is_language_independent(context)) shared_folder_url = site_url + '/folder_contents' pc = getToolByName(getSite(), 'portal_catalog') results = pc.unrestrictedSearchResults( portal_type='LIF', Language=ILanguage(context).get_language()) for brain in results: shared_folder_url = brain.getURL() + '/folder_contents' if not is_neutral_content and not INavigationRoot.providedBy(context): menu.append({ "title": _(u"title_babel_edit", default=u"Edit with babel view"), "description": _(u"description_babel_edit", default=u"Edit with the babel_edit"), "action": url + "/" + edit_view, "selected": False, "icon": None, "extra": { "id": "_edit_babel_edit", "separator": None, "class": "", }, "submenu": None, }) if ITranslatable.providedBy(context): contexts = [ context, ] else: contexts = [] prt = aq_parent(context) if is_default_page(prt, context) and ITranslatable.providedBy(prt): contexts.append(prt) for idx, context in enumerate(contexts): url = context.absolute_url() ulangs = untranslated_languages(context) for lang in ulangs: lang_name = lang_names.get(lang.value, lang.title) lang_id = lang.value icon = showflags and lt.getFlagForLanguageCode(lang_id)\ or None item = { "description": _(u"description_translate_into", default=u"Translate into ${lang_name}", mapping={"lang_name": lang_name}), "action": "%s/@@create_translation?language=%s" % (url, lang_id), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": { "id": "translate_into_%s" % lang_id, "separator": None, "class": "contentmenuflags" }, "submenu": None, } item['title'] = idx and _( u'create_translation_folder', default=u"Create ${lang_name} folder", mapping={"lang_name": lang_name}) or _( u'create_translation', default=u"Create ${lang_name}", mapping={"lang_name": lang_name}) menu.append(item) langs = translated_languages(context) urls = translated_urls(context) for lang in langs: 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 = showflags and lt.getFlagForLanguageCode(lang_id)\ or None item = { "description": _(u"description_babeledit_menu", default=u"Babel edit ${lang_name}", mapping={"lang_name": lang_name}), "action": (urls.getTerm(lang_id).title + "/" + edit_view), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": { "id": "babel_edit_%s" % lang_id, "separator": None, "class": "contentmenuflags" }, "submenu": None, } item['title'] = idx and _( u'edit_translation_folder', default=u"Edit ${lang_name} folder", mapping={"lang_name": lang_name}) or _( u'edit_translation', default=u"Edit ${lang_name}", mapping={"lang_name": lang_name}) menu.append(item) item = { "description": _(u"description_add_translations", default=u"Add existing content as translation"), "action": url + "/add_translations", "selected": False, "icon": None, "extra": { "id": "_add_translations", "separator": langs and "actionSeparator" or None, "class": "" }, "submenu": None, } item['title'] = idx and _( u"title_add_translations_folder", default=u"Add translations for folder...") or _( u"title_add_translations", default=u"Add translations...") menu.append(item) item = { "title": _(u"title_remove_translations", default=u"Remove translations..."), "description": _(u"description_remove_translations", default=u"Delete translations or remove the relations"), "action": url + "/remove_translations", "selected": False, "icon": None, "extra": { "id": "_remove_translations", "separator": langs and "actionSeparator" or None, "class": "" }, "submenu": None, } menu.append(item) elif is_neutral_content: menu.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 + '/' + lt.getPreferredLanguage(), "selected": False, "icon": None, "extra": { "id": "_shared_folder", "separator": None, "class": "" }, "submenu": None, }) if not is_neutral_content: menu.append({ "title": _(u"universal_link", default=u"Universal Link"), "description": _(u"description_universal_link", default=u"Universal Language content link"), "action": "%s/@@multilingual-universal-link/%s" % (site_url, context_id), "selected": False, "icon": None, "extra": { "id": "_universal_link", "separator": None, "class": "" }, "submenu": None, }) menu.append({ "title": _(u"shared_folder", default=u"Go to shared folder"), "description": _(u"description_shared_folder", default=u"Show the language shared (neutral language) " u"folder"), "action": shared_folder_url, "selected": False, "icon": None, "extra": { "id": "_shared_folder", "separator": None, "class": "" }, "submenu": None, }) menu.append({ "title": _(u"title_set_language", default=u"Set content language"), "description": _(u"description_set_language", default=u"Set or change the current content language"), "action": url + "/update_language", "selected": False, "icon": None, "extra": { "id": "_set_language", "separator": None, "class": "" }, "submenu": None, }) return menu
def test_moving_shared_content_to_lrf(self): # Create shared document createContentInContainer( self.portal, 'LIF', title=u"Assets", checkConstraints=False) createContentInContainer( self.portal.assets, 'Document', title=u"Test document") uuid = IUUID(self.portal.assets['test-document']) # Check that ghost is ghost self.assertTrue( is_language_independent(self.portal.ca.assets['test-document'])) # Check is in the catalog brains = self.portal.portal_catalog.searchResults(UID=uuid) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/assets/test-document') brains = self.portal.portal_catalog.searchResults( UID='{0:s}-ca'.format(uuid)) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/ca/assets/test-document') brains = self.portal.portal_catalog.searchResults( UID='{0:s}-es'.format(uuid)) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/es/recursos/test-document') # MOVE! moved = multilingualMoveObject( self.portal.ca.assets['test-document'], 'ca') # Check that the old and the new uuid are the same moved_uuid = IUUID(self.portal.ca['test-document']) self.assertEqual(uuid, moved_uuid) self.assertFalse(is_language_independent(moved)) # Check portal_catalog is updated after move brains = self.portal.portal_catalog.searchResults(UID=uuid) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/ca/test-document') brains = self.portal.portal_catalog.searchResults( UID='{0:s}-ca'.format(uuid)) self.assertEqual(len(brains), 0) brains = self.portal.portal_catalog.searchResults( UID='{0:s}-es'.format(uuid)) self.assertEqual(len(brains), 0) # Check which translations it have self.assertEqual( ITranslationManager(moved).get_translations(), {'ca': moved}) ITranslationManager(moved).add_translation('es') self.assertEqual( ITranslationManager(moved).get_translations(), {'ca': moved, 'es': self.portal.es['test-document']}) # Check that ghost is no longer ghost self.assertFalse( is_language_independent(self.portal.es['test-document']))
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
def test_moving_shared_content_to_lrf(self): # Create shared document createContentInContainer( self.portal, 'LIF', title=u"Assets", checkConstraints=False) createContentInContainer( self.portal.assets, 'Document', title=u"Test document") uuid = IUUID(self.portal.assets['test-document']) # Check that ghost is ghost self.assertTrue( is_language_independent(self.portal.ca.recursos['test-document'])) # Check is in the catalog brains = self.portal.portal_catalog.searchResults(UID=uuid) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/assets/test-document') brains = self.portal.portal_catalog.searchResults( UID='{0:s}-ca'.format(uuid)) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/ca/recursos/test-document') brains = self.portal.portal_catalog.searchResults( UID='{0:s}-es'.format(uuid)) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/es/recursos/test-document') # MOVE! moved = multilingualMoveObject( self.portal.ca.recursos['test-document'], 'ca') # Check that the old and the new uuid are the same moved_uuid = IUUID(self.portal.ca['test-document']) self.assertEqual(uuid, moved_uuid) self.assertFalse(is_language_independent(moved)) # Check portal_catalog is updated after move brains = self.portal.portal_catalog.searchResults(UID=uuid) self.assertEqual(len(brains), 1) self.assertEqual(brains[0].getPath(), '/plone/ca/test-document') brains = self.portal.portal_catalog.searchResults( UID='{0:s}-ca'.format(uuid)) self.assertEqual(len(brains), 0) brains = self.portal.portal_catalog.searchResults( UID='{0:s}-es'.format(uuid)) self.assertEqual(len(brains), 0) # Check which translations it have self.assertEqual( ITranslationManager(moved).get_translations(), {'ca': moved}) ITranslationManager(moved).add_translation('es') self.assertEqual( ITranslationManager(moved).get_translations(), {'ca': moved, 'es': self.portal.es['test-document']}) # Check that ghost is no longer ghost self.assertFalse( is_language_independent(self.portal.es['test-document']))
def getMenuItems(self, context, request): """Return menu item entries in a TAL-friendly form. """ try: lang_names = request.locale.displayNames.languages except AttributeError: lang_names = {} menu = [] url = context.absolute_url() lt = getToolByName(context, "portal_languages") site_url = getSite().absolute_url() showflags = lt.showFlags context_id = ITranslationManager(context).tg registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema, prefix="plone") edit_view = 'babel_edit' if settings.redirect_babel_view else 'edit' # In case is neutral language show set language menu only is_neutral_content = ( ILanguage(context).get_language() == LANGUAGE_INDEPENDENT or is_language_independent(context) ) shared_folder_url = site_url + '/folder_contents' pc = getToolByName(getSite(), 'portal_catalog') results = pc.unrestrictedSearchResults( portal_type='LIF', Language=ILanguage(context).get_language()) for brain in results: shared_folder_url = brain.getURL() + '/folder_contents' if not is_neutral_content and not INavigationRoot.providedBy(context): menu.append({ "title": _( u"title_babel_edit", default=u"Edit with babel view" ), "description": _( u"description_babel_edit", default=u"Edit with the babel_edit" ), "action": url + "/" + edit_view, "selected": False, "icon": None, "extra": { "id": "_edit_babel_edit", "separator": None, "class": "", }, "submenu": None, }) if ITranslatable.providedBy(context): contexts = [context, ] else: contexts = [] prt = aq_parent(context) if isDefaultPage(prt, context) and ITranslatable.providedBy(prt): contexts.append(prt) for idx, context in enumerate(contexts): url = context.absolute_url() ulangs = untranslated_languages(context) for lang in ulangs: lang_name = lang_names.get(lang.value, lang.title) lang_id = lang.value icon = showflags and lt.getFlagForLanguageCode(lang_id)\ or None item = { "description": _( u"description_translate_into", default=u"Translate into ${lang_name}", mapping={"lang_name": lang_name} ), "action": "%s/@@create_translation?language=%s" % ( url, lang_id), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": {"id": "translate_into_%s" % lang_id, "separator": None, "class": "contentmenuflags"}, "submenu": None, } item['title'] = idx and _( u'create_translation_folder', default=u"Create ${lang_name} folder", mapping={"lang_name": lang_name} ) or _( u'create_translation', default=u"Create ${lang_name}", mapping={"lang_name": lang_name} ) menu.append(item) langs = translated_languages(context) urls = translated_urls(context) for lang in langs: 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 = showflags and lt.getFlagForLanguageCode(lang_id)\ or None item = { "description": _( u"description_babeledit_menu", default=u"Babel edit ${lang_name}", mapping={"lang_name": lang_name} ), "action": (urls.getTerm(lang_id).title + "/" + edit_view), "selected": False, "icon": icon, "width": "14", "height": "11", "extra": {"id": "babel_edit_%s" % lang_id, "separator": None, "class": "contentmenuflags"}, "submenu": None, } item['title'] = idx and _( u'edit_translation_folder', default=u"Edit ${lang_name} folder", mapping={"lang_name": lang_name} ) or _( u'edit_translation', default=u"Edit ${lang_name}", mapping={"lang_name": lang_name} ) menu.append(item) item = { "description": _( u"description_add_translations", default=u"Add existing content as translation"), "action": url + "/add_translations", "selected": False, "icon": None, "extra": { "id": "_add_translations", "separator": langs and "actionSeparator" or None, "class": "" }, "submenu": None, } item['title'] = idx and _( u"title_add_translations_folder", default=u"Add translations for folder..." ) or _( u"title_add_translations", default=u"Add translations..." ) menu.append(item) item = { "title": _( u"title_remove_translations", default=u"Remove translations..." ), "description": _( u"description_remove_translations", default=u"Delete translations or remove the relations" ), "action": url + "/remove_translations", "selected": False, "icon": None, "extra": { "id": "_remove_translations", "separator": langs and "actionSeparator" or None, "class": "" }, "submenu": None, } menu.append(item) elif is_neutral_content: menu.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 + '/' + lt.getPreferredLanguage(), "selected": False, "icon": None, "extra": { "id": "_shared_folder", "separator": None, "class": "" }, "submenu": None, }) if not is_neutral_content: menu.append({ "title": _( u"universal_link", default=u"Universal Link" ), "description": _( u"description_universal_link", default=u"Universal Language content link" ), "action": "%s/@@multilingual-universal-link/%s" % ( site_url, context_id), "selected": False, "icon": None, "extra": { "id": "_universal_link", "separator": None, "class": "" }, "submenu": None, }) menu.append({ "title": _( u"shared_folder", default=u"Go to shared folder" ), "description": _( u"description_shared_folder", default=u"Show the language shared (neutral language) " u"folder" ), "action": shared_folder_url, "selected": False, "icon": None, "extra": { "id": "_shared_folder", "separator": None, "class": ""}, "submenu": None, }) menu.append({ "title": _( u"title_set_language", default=u"Set content language" ), "description": _( u"description_set_language", default=u"Set or change the current content language" ), "action": url + "/update_language", "selected": False, "icon": None, "extra": { "id": "_set_language", "separator": None, "class": "" }, "submenu": None, }) return menu
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