def get_all_translations(self, content): """Return all translations excluding the just modified content""" content_lang = queryAdapter(content, ILanguage).get_language() translations = ITranslationManager(content).get_translated_languages() while content_lang in translations: translations.remove(content_lang) return translations
def __call__(self): pc = getToolByName(self.context, 'portal_catalog') pl = getToolByName(self.context, 'portal_languages') self.results = [] for language_supported in pl.getSupportedLanguages(): translated_objects = pc.searchResults( object_provides=LP_TRANSLATABLE, Language=language_supported) for brain in translated_objects: obj = brain.getObject() if obj.isCanonical(): translations = obj.getTranslations(include_canonical=False) manager = ITranslationManager(obj) if translations: for language in translations.keys(): try: manager.register_translation( language, translations[language][0]) except KeyError: logger.info( '%s already translated to %s: %s' % (obj.id, language, str(manager.get_translations()))) self.results.append(str(manager.get_translations())) logger.info('Finished with transferring catalog information') return self.template()
def handle_modified(self, content): fieldmanager = ILanguageIndependentFieldsManager(content) if not fieldmanager.has_independent_fields(): return sm = getSecurityManager() try: # Do we have permission to sync language independent fields? if self.bypass_security_checks(): # Clone the current user and assign a new editor role to # allow edition of all translated objects even if the # current user whould not have permission to do that. tmp_user = UnrestrictedUser( sm.getUser().getId(), '', ['Editor', ], '') # Wrap the user in the acquisition context of the portal # and finally switch the user to our new editor acl_users = getToolByName(content, 'acl_users') tmp_user = tmp_user.__of__(acl_users) newSecurityManager(None, tmp_user) # Copy over all language independent fields transmanager = ITranslationManager(content) for translation in self.get_all_translations(content): trans_obj = transmanager.get_translation(translation) if fieldmanager.copy_fields(trans_obj): self.reindex_translation(trans_obj) finally: # Restore the old security manager setSecurityManager(sm)
def setContentsInActionMenu(self, value): self.settings.contents_in_action_menu = value portal = root = api.portal.get() if 'fr' in root.objectIds(): fr = getattr(root, 'fr') root = api.portal.get_navigation_root(fr) catalog = api.portal.get_tool('portal_catalog') name = 'cpskin.core.vocabularies.action_menu_eligible' factory = getUtility(IVocabularyFactory, name) vocabulary = factory(portal) all_values = vocabulary.by_value.keys() for content_id in all_values: content = getattr(root, content_id, None) if not content: continue translations = {'fr': content} request = getattr(self.context, 'REQUEST', None) if is_plone_app_multilingual_installed(request): translations = ITranslationManager(content).get_translations() if content_id in value: for t in translations.values(): if IElectedContentForTopMenu.providedBy(t): continue alsoProvides(t, IElectedContentForTopMenu) catalog.reindexObject(t) else: for t in translations.values(): if not IElectedContentForTopMenu.providedBy(t): continue noLongerProvides(t, IElectedContentForTopMenu) catalog.reindexObject(t)
def __call__(self): language = self.request.get('language', None) if language: context = aq_inner(self.context) translation_manager = ITranslationManager(context) # if ILanguage(context).get_language() == LANGUAGE_INDEPENDENT: # # XXX : Why we need this ? the subscriber from pm should # maintain it # language_tool = getToolByName(context, 'portal_languages') # default_language = language_tool.getDefaultLanguage() # ILanguage(context).set_language(default_language) # translation_manager.update() # context.reindexObject() new_parent = translation_manager.add_translation_delegated(language) # noqa registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema) sdm = self.context.session_data_manager session = sdm.getSessionData(create=True) session.set("tg", translation_manager.tg) session.set("old_lang", ILanguage(self.context).get_language()) baseUrl = new_parent.absolute_url() # We set the language and redirect to babel_view or not if settings.redirect_babel_view: # Call the ++addtranslation++ adapter to show the babel # add form url = '%s/++addtranslation++%s' % ( baseUrl, self.context.portal_type) return self.request.response.redirect(url) else: # We look for the creation url for this content type # Get the factory types_tool = getToolByName(self.context, 'portal_types') # Note: we don't check 'allowed' or 'available' here, # because these are slow. We assume the 'allowedTypes' # list has already performed the necessary calculations actions = types_tool.listActionInfos( object=new_parent, check_permissions=False, check_condition=False, category='folder/add', ) addActionsById = dict([(a['id'], a) for a in actions]) typeId = self.context.portal_type addAction = addActionsById.get(typeId, None) if addAction is not None: url = addAction['url'] if not url: url = '%s/createObject?type_name=%s' % ( baseUrl, quote_plus(typeId)) return self.request.response.redirect(url)
def test_add_translation_delegated(self): a_ca = createContentInContainer( self.portal['ca'], 'Document', title=u"Test document") translation_manager = ITranslationManager(a_ca) portal_es = translation_manager.add_translation_delegated('es') self.assertEqual(portal_es, self.portal['es'])
def __call__(self): language = self.request.get('language', None) if language: context = aq_inner(self.context) translation_manager = ITranslationManager(context) new_parent = translation_manager.add_translation_delegated(language) # noqa baseUrl = new_parent.absolute_url() url = '%s/++addtranslation++%s' % (baseUrl, IUUID(context)) return self.request.response.redirect(url)
def handle_unlink(self, action): data, errors = self.extractData() manager = ITranslationManager(self.context) if not errors: for language in data['languages']: manager.remove_translation(language) return self.request.response.redirect( self.context.absolute_url() + '/remove_translations')
def __init__(self, context, request): super(BabelUtils, self).__init__(context, request) portal_state = getMultiAdapter((context, request), name="plone_portal_state") self.portal_url = portal_state.portal_url() # If there is any translation_info lets use it try: self.group = TranslationManager(request.translation_info['tg']) except AttributeError: self.group = ITranslationManager(self.context)
def handle_remove(self, action): data, errors = self.extractData() manager = ITranslationManager(self.context) if not errors: for language in data['languages']: content = manager.get_translation(language) manager.remove_translation(language) aq_parent(content).manage_delObjects([content.getId()]) return self.request.response.redirect( self.context.absolute_url() + '/remove_translations')
def get_all_translations(self, content): """Return all translations excluding the just modified content""" translations_list_to_process = [] content_lang = queryAdapter(content, ILanguage).get_language() canonical = ITranslationManager(content) translations = canonical.get_translations() for language in translations.keys(): if language != content_lang: translations_list_to_process.append(translations[language]) return translations_list_to_process
def __init__(self, context, request): super(BabelUtils, self).__init__(context, request) portal_state = getMultiAdapter((context, request), name="plone_portal_state") self.portal_url = portal_state.portal_url() # If there is any session tg lets use the session tg sdm = self.context.session_data_manager session = sdm.getSessionData(create=True) if 'tg' in session.keys(): self.group = TranslationManager(session['tg']) else: self.group = ITranslationManager(self.context)
def link_translations(items): """ Links the translations with the declared items with the form: [(obj1, lang1), (obj2, lang2), ...] assuming that the first element is the 'canonical' (in PAM there is no such thing). """ # Grab the first item object and get its canonical handler canonical = ITranslationManager(items[0][0]) for obj, language in items: if not canonical.has_translation(language): canonical.register_translation(language, obj)
def test_multilingual_content_is_linked(self): english_content = self.portal.get('en').get('accessibility') self.assertIsNotNone(english_content, 'Missing page /en/accessibility') german_content = self.portal.get('de').get('barrierefreiheit') self.assertIsNotNone(german_content, 'Missing page /de/barrierefreiheit') manager = ITranslationManager(english_content) self.assertEquals(german_content, manager.get_translation('de'), 'English and German content should be linked.')
def translated_urls(context): manager = ITranslationManager(context) translated_languages = manager.get_translated_languages() content_language = ILanguage(context).get_language() if content_language in translated_languages: translated_languages.remove(content_language) languages = [] for lang in translated_languages: translation = manager.get_restricted_translation(lang) if translation is not None: term = SimpleVocabulary.createTerm(lang, lang, translation.absolute_url()) languages.append(term) return SimpleVocabulary(languages)
def deletable_languages(context): manager = ITranslationManager(context) translated_languages = manager.get_translated_languages() language_tool = getToolByName(context, "portal_languages") language_infos = language_tool.getAvailableLanguages() content_language = ILanguage(context).get_language() languages = [] for lang in translated_languages: if lang not in content_language: 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 createdEvent(obj, event): """ Subscriber to set language on the child folder It can be a - IObjectRemovedEvent - don't do anything - IObjectMovedEvent - IObjectAddedEvent - IObjectCopiedEvent """ if IObjectRemovedEvent.providedBy(event): return request = getattr(event.object, 'REQUEST', getRequest()) if not IPloneAppMultilingualInstalled.providedBy(request): return # On ObjectCopiedEvent and ObjectMovedEvent aq_parent(event.object) is # always equal to event.newParent. parent = aq_parent(event.object) # special parent handling if not ITranslatable.providedBy(parent): set_recursive_language(obj, LANGUAGE_INDEPENDENT) return # Normal use case # We set the tg, linking language = ILanguage(parent).get_language() set_recursive_language(obj, language) request = getattr(event.object, 'REQUEST', getRequest()) try: ti = request.translation_info except AttributeError: return # AT check portal = getSite() portal_factory = getToolByName(portal, 'portal_factory', None) if ( not IDexterityContent.providedBy(obj) and portal_factory is not None and not portal_factory.isTemporary(obj) ): return IMutableTG(obj).set(ti['tg']) modified(obj) tm = ITranslationManager(obj) old_obj = tm.get_translation(ti['source_language']) ILanguageIndependentFieldsManager(old_obj).copy_fields(obj)
def test_duplicate_translations_are_discarded_when_linking(self): folder_uhoh = create(Builder('folder').titled(u'uhoh')) self.items = self.items[:2] self.items.append({ '_path': '/uhoh', '_canonicalTranslation': False, '_translationOf': '/de', 'language': 'en', }) items = self._run_transmogrifier() self.assertEqual(3, len(items)) uhoh_manager = ITranslationManager(folder_uhoh) manager = ITranslationManager(self.folder_en) uhoh_manager.update() manager.update() self.assertEqual('en', ILanguage(folder_uhoh).get_language()) self.assertEqual(1, len(uhoh_manager.get_translated_languages())) languages = manager.get_translated_languages() self.assertEqual(2, len(languages)) self.assertIn('de', languages) self.assertIn('en', languages)
def __call__(self, language): """ Look for the closest translated folder or siteroot """ parent = aq_parent(self.context) translated_parent = parent found = False while not (IPloneSiteRoot.providedBy(parent) and not ILanguageRootFolder.providedBy(parent)) and not found: parent_translation = ITranslationManager(parent) if parent_translation.has_translation(language): translated_parent = \ parent_translation.get_translation(language) found = True parent = aq_parent(parent) return translated_parent
def translated_languages(context): language_tool = getToolByName(context, "portal_languages") language_infos = language_tool.getAvailableLanguages() manager = ITranslationManager(context) # take care to filter out translated contents # wich do no have supported language information translated_languages = [a for a in manager.get_translated_languages() if a in language_infos] content_language = ILanguage(context).get_language() if content_language in translated_languages: translated_languages.remove(content_language) languages = [] for lang 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 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_shared(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 test_get_translation_manager(self): a_ca = createContentInContainer( self.portal['ca'], 'Document', title=u"Test document" ) tm = api.get_translation_manager(a_ca) self.assertTrue(ITranslationManager.providedBy(tm))
def get_alternate_languages(self): """Cache relative urls only. If we have multilingual sites and multi domain site caching absolute urls will result in very inefficient caching. Build absolute url in template. """ tm = ITranslationManager(self.context) catalog = getToolByName(self.context, 'portal_catalog') results = catalog(TranslationGroup=tm.query_canonical()) alternates = [] for item in results: url = item.getURL() alternates.append({ 'lang': item.Language, 'url': url, }) return alternates
def __call__(self): if self.request.form.get('submitted'): language = self.request.form['language'] catalog = getToolByName(self.context, 'portal_catalog') context = catalog.unrestrictedSearchResults( UID=self.request.form['came_from']) if context: context = context[0].getObject() if language and context: manager = ITranslationManager(context) try: manager.remove_translation(language) except Exception, e: messages = IStatusMessage(self.request) messages.addStatusMessage(e, type='error') return self.request.response.redirect( context.absolute_url() + '/modify_translations')
def __call__(self): if (self.request.method != 'POST' and not ('field' in self.request.form.keys() and 'lang_source' in self.request.form.keys())): return _("Need a field") else: manager = ITranslationManager(self.context) registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema) lang_target = ILanguage(self.context).get_language() lang_source = self.request.form['lang_source'] orig_object = manager.get_translation(lang_source) field = self.request.form['field'].split('.')[-1] if hasattr(orig_object, field): question = getattr(orig_object, field, '') if hasattr(question, 'raw'): question = question.raw else: return _("Invalid field") return google_translate(question, settings.google_translation_key, lang_target, lang_source)
def _update_deferred(self): for path, canonicalpath, language in self.deferred: obj = self._traverse(path) if obj is None: continue canonical = self._traverse(canonicalpath) if canonical is None: continue if (ITranslatable.providedBy(obj) and ITranslatable.providedBy(canonical)): try: translation_group = IMutableTG(canonical).get() IMutableTG(obj).set(translation_group) manager = ITranslationManager(obj) manager.register_translation(language, obj) except KeyError: # put obj in a separate translation group when registration # fails IMutableTG(obj).set(self.uuid_generator())
def __call__(self): if (self.request.method != 'POST' and not ('field' in self.request.form.keys() and 'lang_source' in self.request.form.keys())): return _("Need a field") else: manager = ITranslationManager(self.context) registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema) lang_target = ILanguage(self.context).get_language() lang_source = self.request.form['lang_source'] orig_object = manager.get_translation(lang_source) try: question = orig_object.getField( self.request.form['field']).get(orig_object) except AttributeError: return _("Invalid field") return google_translate( question, settings.google_translation_key, lang_target, lang_source )
def create_translation(self, *args, **kwargs): """Create translation for an object with uid in the given target_language and return its UID Usage:: Create translation /plone/en/foo ca title=Translated """ disableCSRFProtection() # Parse arguments: uid_or_path = args[0] target_language = args[1] # BBB: Support keywords arguments with robotframework < 2.8.3 kwargs.update(dict([arg.split('=', 1) for arg in args[2:]])) # Look up translatable content pc = getToolByName(self, "portal_catalog") uid_results = pc.unrestrictedSearchResults(UID=uid_or_path) path_results = pc.unrestrictedSearchResults( path={'query': uid_or_path.rstrip('/'), 'depth': 0}) obj = (uid_results or path_results)[0]._unrestrictedGetObject() # Translate manager = ITranslationManager(obj) manager.add_translation(target_language) translation = manager.get_translation(target_language) # Update fields data = constructMessageFromSchemata(obj, iterSchemata(obj)) for key, value in kwargs.items(): del data[key] data[key] = Header(value, 'utf-8') del data['language'] initializeObjectFromSchemata(translation, iterSchemata(obj), data) notify(ObjectModifiedEvent(translation)) # Return uid for the translation return IUUID(translation)
def get_alternate_languages(self): """Cache relative urls only. If we have multilingual sites and multi domain site caching absolute urls will result in very inefficient caching. Build absolute url in template. """ tm = ITranslationManager(self.context) catalog = getToolByName(self.context, 'portal_catalog') results = catalog(TranslationGroup=tm.query_canonical()) plone_site = getUtility(IPloneSiteRoot) portal_path = '/'.join(plone_site.getPhysicalPath()) portal_path_len = len(portal_path) alternates = [] for item in results: path_len = portal_path_len + len('{0:s}/'.format(item.Language)) url = item.getURL(relative=1)[path_len:] alternates.append({ 'lang': item.Language, 'url': url.strip('/'), }) return alternates
def linkTranslations(self): """Links the translations of the default language Folders """ doneSomething = False try: canonical = ITranslationManager(self.folders[self.defaultLanguage]) except TypeError as e: raise TypeError(str(e) + u' Are your folders ITranslatable?') for language in self.languages: if language == self.defaultLanguage: continue if not canonical.has_translation(language): language_folder = self.folders[language] canonical.register_translation(language, language_folder) doneSomething = True if doneSomething: logger.info(u'Translations linked.') return doneSomething
def test_get_translations(self): translations = ITranslationManager(self.a_ca).get_translations() self.assertEqual(translations, {'ca': self.a_ca})
def test_add_translation_delegated(self): # Create es translation portal_es = ITranslationManager( self.a_ca).add_translation_delegated('es') self.assertEqual(portal_es, self.portal['es'])
def test_get_translation_manager(self): a_ca = createContentInContainer(self.portal['ca'], 'Document', title=u"Test document") tm = api.get_translation_manager(a_ca) self.assertTrue(ITranslationManager.providedBy(tm))
def getClosestDestination(self): """Get the "closest translated object" URL. """ # We should travel the parent chain using the catalog here, # but I think using the acquisition chain is faster # (or well, __parent__ pointers) because the catalog # would require a lot of queries, while technically, # having done traversal up to this point you should # have the objects in memory already # As we don't have any content object we are going to look # for the best option site = getSite() root = getToolByName(site, 'portal_url') ltool = getToolByName(site, 'portal_languages') # We are using TranslationManager to get the translations of a # string tg try: manager = TranslationManager(self.tg) languages = manager.get_translations() except AttributeError: languages = [] if len(languages) == 0: # If there is no results there are no translations # we move to portal root return self.wrapDestination(root(), postpath=False) # We are going to see if there is the preferred language translation # Otherwise we get the first as context to look for translation prefered = ltool.getPreferredLanguage(self.request) if prefered in languages: context = languages[prefered] else: context = languages[list(languages.keys())[0]] checkPermission = getSecurityManager().checkPermission chain = self.getParentChain(context) for item in chain: if ISiteRoot.providedBy(item) \ and not ILanguageRootFolder.providedBy(item): # We do not care to get a permission error # if the whole of the portal cannot be viewed. # Having a permission issue on the root is fine; # not so much for everything else so that is checked there return self.wrapDestination(item.absolute_url()) elif IFactoryTempFolder.providedBy(item) or \ IFactoryTool.providedBy(item): # TempFolder or portal_factory, can't have a translation continue try: canonical = ITranslationManager(item) except TypeError: if not ITranslatable.providedBy(item): # In case there it's not translatable go to parent # This solves the problem when a parent is not # ITranslatable continue else: raise translation = canonical.get_translation(self.lang) if translation and (INavigationRoot.providedBy(translation) or bool(checkPermission('View', translation))): # Not a direct translation, therefore no postpath # (the view might not exist on a different context) return self.wrapDestination(translation.absolute_url(), postpath=False) # Site root's the fallback return self.wrapDestination(root(), postpath=False)
def test_get_restricted_translation_for_anonymous(self): logout() restricted_translations = \ ITranslationManager(self.a_ca).get_restricted_translations() self.assertEqual(restricted_translations, {})
def reply(self): data = json_body(self.request) type_ = data.get("@type", None) id_ = data.get("id", None) title = data.get("title", None) translation_of = data.get("translation_of", None) language = data.get("language", None) uid = data.get("UID", None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) sm = getSecurityManager() # ManagePortal is required to set the uid of an object during creation if uid and not sm.checkPermission(ManagePortal, self.context): self.request.response.setStatus(403) msg = "Setting UID of an object requires Manage Portal permission" return dict(error=dict(type="Forbidden", message=msg)) try: obj = create(self.context, type_, id_=id_, title=title) except Unauthorized as exc: self.request.response.setStatus(403) return dict(error=dict(type="Forbidden", message=str(exc))) except BadRequest as exc: self.request.response.setStatus(400) return dict(error=dict(type="Bad Request", message=str(exc))) # Acquisition wrap temporarily to satisfy things like vocabularies # depending on tools temporarily_wrapped = False if IAcquirer.providedBy(obj) and not safe_hasattr(obj, "aq_base"): obj = obj.__of__(self.context) temporarily_wrapped = True # Update fields deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict(error=dict( message=f"Cannot deserialize type {obj.portal_type}")) try: deserializer(validate_all=True, create=True) except DeserializationError as e: self.request.response.setStatus(400) return dict( error=dict(type="DeserializationError", message=str(e))) if temporarily_wrapped: obj = aq_base(obj) if uid: setattr(obj, "_plone.uuid", uid) if not getattr(deserializer, "notifies_create", False): notify(ObjectCreatedEvent(obj)) obj = add(self.context, obj, rename=not bool(id_)) # Link translation given the translation_of property if (IPloneAppMultilingualInstalled.providedBy(self.request) and translation_of and language): source = self.get_object(translation_of) if source: manager = ITranslationManager(source) manager.register_translation(language, obj) self.request.response.setStatus(201) self.request.response.setHeader("Location", obj.absolute_url()) serializer = queryMultiAdapter((obj, self.request), ISerializeToJson) serialized_obj = serializer() # HypermediaBatch can't determine the correct canonical URL for # objects that have just been created via POST - so we make sure # to set it here serialized_obj["@id"] = obj.absolute_url() return serialized_obj
def get_all_translations(self, content): """Return all translations excluding the just modified content""" content_lang = queryAdapter(content, ILanguage).get_language() translations = ITranslationManager(content).get_translated_languages() translations.remove(content_lang) return translations
def get_dexterity_fields(self): """If dexterity is used then extract fields. """ try: from plone.dexterity.interfaces import IDexterityContent if not self.providedBy(IDexterityContent, self.context): return from plone.dexterity.utils import iterSchemata # from plone.uuid.interfaces import IUUID from zope.schema import getFieldsInOrder from datetime import date except: return # get translation if thereis try: if self.is_multilingual() and self.has_tg and len( ITranslationManager(self.context).get_translations()) > 1: trans = ITranslationManager(self.context).get_translations() else: trans = {} except: trans = {} if len(trans) > 1: translations = ITranslationManager(self.context).get_translations() portal_level = len(self.portal.getPhysicalPath()) trans = {} for lang, obj in translations.items(): trans[lang] = '/' + '/'.join( obj.getPhysicalPath()[portal_level:]) self['translations'] = trans # get all fields for this obj for schemata in iterSchemata(self.context): for fieldname, field in getFieldsInOrder(schemata): try: value = field.get(schemata(self.context)) # value = getattr(context, name).__class__.__name__ except AttributeError: continue if value is field.missing_value: continue field_type = field.__class__.__name__ if field_type in ('RichText', ): # XXX: content_type missing try: value = unicode(value.raw) except: value = u'' elif field_type in ('NamedImage', 'NamedBlobImage', 'NamedFile', 'NamedBlobFile'): # still to test above with NamedFile & NamedBlobFile fieldname = unicode('_datafield_' + fieldname) if hasattr(value, 'open'): data = value.open().read() else: data = value.data try: max_filesize = int( os.environ.get('JSONIFY_MAX_FILESIZE', 20000000)) except ValueError: max_filesize = 20000000 if data and len(data) > max_filesize: continue import base64 ctype = value.contentType size = value.getSize() dvalue = { 'data': base64.b64encode(data), 'size': size, 'filename': value.filename or '', 'content_type': ctype, 'encoding': 'base64' } value = dvalue elif field_type == 'GeolocationField': # super special plone.formwidget.geolocation case self['latitude'] = getattr(value, 'latitude', 0) self['longitude'] = getattr(value, 'longitude', 0) continue elif field_type == 'ContactChoice': pos = getattr(self.context, fieldname, None) if pos: value = unicode(pos.to_path) elif isinstance(value, date): value = value.isoformat() # elif field_type in ('TextLine',): else: BASIC_TYPES = (unicode, int, long, float, bool, type(None), list, tuple, dict) if type(value) in BASIC_TYPES: pass else: # E.g. DateTime or datetime are nicely representated value = unicode(value) self[unicode(fieldname)] = value
def import_item(self, dirpath, *filenames): __traceback_info__ = dirpath logger.info("Importing item at %s", dirpath) all_info = {} blobs = {} for name in filenames: filepath = os.path.join(dirpath, name) key, ext = os.path.splitext(name) if ext != ".json": logger.info("Found non json file, will use as blob, at %s", filepath) blobs[key] = filepath continue logger.info("Reading %s", filepath) with open(filepath) as myfile: content = json.loads(myfile.read()) all_info[key] = content # Get meta info. We might also get some of this from default.json. # Maybe we need less in meta. meta = all_info["meta"] # if "front-page" in meta.get("path", ""): # import pdb; pdb.set_trace() # See if the object already exists. obj = self.get_object(**meta) if obj is None: # We need to get some parent, either from default["parent"] or meta. path = meta["path"] parent_path = path.rpartition("/")[0] parent_obj = self.get_object(path=parent_path) if parent_obj is None: logger.warning( "Parent object not found, cannot create content for %s", path) return default = all_info["default"] # Code taken from plone.restapi add.py FolderPost.reply. # It would be nice if we could call that method directly, but it does too much. # We would need to split it a bit, especially: # don't get json from the request body, and don't change the response. type_ = default.get("@type", None) id_ = default.get("id", None) title = default.get("title", None) translation_of = default.get("translation_of", None) language = default.get("language", None) # except Unauthorized / BadRequest obj = create(parent_obj, type_, id_=id_, title=title) # Acquisition wrap temporarily to satisfy things like vocabularies # depending on tools temporarily_wrapped = False if IAcquirer.providedBy(obj) and not safe_hasattr(obj, "aq_base"): obj = obj.__of__(self.context) temporarily_wrapped = True deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: logger.error("Cannot deserialize type %s", obj.portal_type) return if blobs: for fieldname, path in blobs.items(): if fieldname in default: with open(path, "rb") as myfile: default[fieldname]["data"] = myfile.read() # except DeserializationError as e: deserializer(validate_all=True, data=default, create=True) if temporarily_wrapped: obj = aq_base(obj) if not getattr(deserializer, "notifies_create", False): notify(ObjectCreatedEvent(obj)) obj = add(parent_obj, obj, rename=not bool(id_)) obj_path = "/".join(obj.getPhysicalPath()) logger.info("Created %s at %s", type_, obj_path) # Link translation given the translation_of property if PAM_INSTALLED: # Note: untested. from plone.app.multilingual.interfaces import ( IPloneAppMultilingualInstalled, ) # noqa from plone.app.multilingual.interfaces import ITranslationManager if (IPloneAppMultilingualInstalled.providedBy(self.request) and translation_of and language): source = self.get_object(translation_of) if source: manager = ITranslationManager(source) manager.register_translation(language, obj) # TODO: call other, named deserializers, but they do not work currently anyway. else: obj_path = "/".join(obj.getPhysicalPath()) if is_locked(obj, self.request): # TODO: We could throw an error, but we should probably just unlock. logger.warning("Content is locked: %s", obj_path) logger.info("Updating existing content at %s", obj_path) deserializers = getAdapters((obj, self.request), IDeserializeFromJson) if not deserializers: logger.error("Cannot deserialize type %s", obj.portal_type) return for name, deserializer in deserializers: if not name: name = "default" # XXX This traceback info overrides the previous. # When done in a separate method, it should be fine. # __traceback_info__ = name __traceback_info__ = dirpath, name content = all_info[name] if name == "local_roles": # TODO Fix this in plone.restapi. logger.info( "Ignoring local_roles deserializer for now, as it does not accept a content parameter." ) continue if name == "default" and blobs: for fieldname, path in blobs.items(): if fieldname in content: with open(path, "rb") as myfile: content[fieldname]["data"] = myfile.read() try: deserializer(data=content) except TypeError: # Happens for site root. But I want to fix it there too, if that is acceptable. logger.info( "TypeError, likely because deserializer does not accept data keyword argument: %s", deserializer) # TODO: maybe try / except DeserializationError # Report back that we made an import. return True
def makeTranslation(content, language='en'): manager = ITranslationManager(content) manager.add_translation(language) return manager.get_translation(language)
def get_archetypes_fields(self): """ If Archetypes is used then dump schema """ try: from Products.Archetypes.interfaces import IBaseObject if not IBaseObject.providedBy(self.context): return except: return if self.is_multilingual() and self.has_tg and len( ITranslationManager( self.context).get_translations()) > 1: # noqa translations = ITranslationManager(self.context).get_translations() portal_level = len(self.portal.getPhysicalPath()) trans = {} for lang, obj in translations.items(): trans[lang] = '/' + '/'.join( obj.getPhysicalPath()[portal_level:]) self['translations'] = trans fields = self.context.Schema().fields() for field in fields: fieldname = unicode(field.__name__) type_ = field.__class__.__name__ fieldnames = [ 'StringField', 'BooleanField', 'LinesField', 'IntegerField', 'TextField', 'SimpleDataGridField', 'FloatField', 'FixedPointField', 'TALESString', 'TALESLines', 'ZPTField', 'DataGridField', 'EmailField', '_StringExtensionField', 'LeadimageCaptionField', 'ExtensionStandardTagsField', 'ExtensionHiddenTagsField', 'ExtensionIAmTagsField', 'ExtensionISearchTagsField', 'CheckboxField' ] if type_ in fieldnames: try: value = field.getRaw(self.context) except AttributeError: value = self._get_at_field_value(field) if callable(value) is True: value = value() if value and type_ in ['StringField', 'TextField']: try: value = self.decode(value) except AttributeError: # maybe an int? value = unicode(value) except Exception, e: raise Exception('problems with %s: %s' % (self.context.absolute_url(), str(e))) elif value and type_ == 'DataGridField': for i, row in enumerate(value): for col_key in row.keys(): col_value = row[col_key] if type(col_value) in (unicode, str): value[i][col_key] = self.decode(col_value) try: ct = field.getContentType(self.context) except AttributeError: ct = '' self[unicode(fieldname)] = value self[unicode('_content_type_') + fieldname] = ct elif type_ in ['DateTimeField']: value = self._get_at_field_value(field) if value: value = DateTime.DateTime.strftime(value, '%Y-%m-%d %H:%M') # value = str(self._get_at_field_value(field)) # value = self._get_at_field_value(field).ISO8601() self[unicode(fieldname)] = value
def already_translated(self): tm = ITranslationManager(self.context) return tm.get_translations()
def translateExhibitions(language="en"): import plone.api import transaction from plone.app.multilingual.interfaces import ITranslationManager from zope.event import notify from zope.lifecycleevent import ObjectModifiedEvent container_path = "/nl/nu-en-verwacht/activiteiten" with plone.api.env.adopt_user(username="******"): container = plone.api.content.get(path=container_path) total = len(list(container)) curr = 0 for _id in list(container): curr += 1 print "Translating Exhibition %s / %s to '%s'" %(curr, total, language) exhibition = container[_id] if exhibition.portal_type == "Event": if not ITranslationManager(exhibition).has_translation(language): ITranslationManager(exhibition).add_translation(language) exhibition_translated = ITranslationManager(exhibition).get_translation(language) exhibition_translated.title = exhibition.title exhibition_translated.start = exhibition.start exhibition_translated.end = exhibition.end exhibition_translated.description = exhibition.description exhibition_translated.text = exhibition.text exhibition_translated.whole_day = exhibition.whole_day exhibition_translated.portal_workflow.doActionFor(exhibition_translated, "publish", comment="published") exhibition_translated.reindexObject() transaction.get().commit() if hasattr(exhibition, 'slideshow'): slideshow = exhibition['slideshow'] ITranslationManager(slideshow).add_translation(language) slideshow_trans = ITranslationManager(slideshow).get_translation(language) slideshow_trans.title = slideshow.title slideshow_trans.portal_workflow.doActionFor(slideshow_trans, "publish", comment="Slideshow published") for sitem in slideshow: if slideshow[sitem].portal_type == "Image": if not ITranslationManager(slideshow[sitem]).has_translation(language): ITranslationManager(slideshow[sitem]).add_translation(language) trans = ITranslationManager(slideshow[sitem]).get_translation(language) trans.image = slideshow[sitem].image exhibition_translated.reindexObject() exhibition_translated.reindexObject(idxs=["hasMedia"]) exhibition_translated.reindexObject(idxs=["leadMedia"]) notify(ObjectModifiedEvent(exhibition_translated)) print "Translation added for Exhibition '%s'" %(exhibition.title) else: print "Exhibition '%s' already has a translation to '%s'" %(exhibition.title, language) print "- Translating slideshow" exhibition_translated = ITranslationManager(exhibition).get_translation(language) if hasattr(exhibition, 'slideshow'): slideshow = exhibition['slideshow'] if ITranslationManager(slideshow).has_translation(language): print "-- Slideshow alredy has a translation." slideshow_trans = ITranslationManager(slideshow).get_translation(language) slideshow_trans.title = slideshow.title try: slideshow_trans.portal_workflow.doActionFor(slideshow_trans, "publish", comment="Slideshow published") except: pass print "--- Translating images" for sitem in slideshow: if slideshow[sitem].portal_type == "Image": if not ITranslationManager(slideshow[sitem]).has_translation(language): ITranslationManager(slideshow[sitem]).add_translation(language) trans = ITranslationManager(slideshow[sitem]).get_translation(language) trans.image = slideshow[sitem].image exhibition_translated.reindexObject() exhibition_translated.reindexObject(idxs=["hasMedia"]) exhibition_translated.reindexObject(idxs=["leadMedia"]) notify(ObjectModifiedEvent(exhibition_translated)) transaction.get().commit() else: print "-- Slideshow doesn't have a translation. Translating slideshow folder." ITranslationManager(slideshow).add_translation(language) slideshow_trans = ITranslationManager(slideshow).get_translation(language) slideshow_trans.title = slideshow.title try: slideshow_trans.portal_workflow.doActionFor(slideshow_trans, "publish", comment="Slideshow published") except: pass print "--- Translating images." for sitem in slideshow: if slideshow[sitem].portal_type == "Image": if not ITranslationManager(slideshow[sitem]).has_translation(language): ITranslationManager(slideshow[sitem]).add_translation(language) trans = ITranslationManager(slideshow[sitem]).get_translation(language) trans.image = slideshow[sitem].image exhibition_translated.reindexObject() exhibition_translated.reindexObject(idxs=["hasMedia"]) exhibition_translated.reindexObject(idxs=["leadMedia"]) notify(ObjectModifiedEvent(exhibition_translated)) transaction.get().commit() print "Slideshow and images for Exhibition '%s' are translated" %(exhibition.title) return True
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 test_get_translation(self): a_ca = ITranslationManager(self.a_ca).get_translation('ca') self.assertEqual(a_ca, self.a_ca)
def do_reply(self): """This is the reply method from plone.restapi, overrided to manage returning the fullobject after creation or the summary.""" # imio.restapi, nothing changed until next comment "imio.restapi ..." comment data = json_body(self.request) type_ = data.get("@type", None) id_ = data.get("id", None) title = data.get("title", None) translation_of = data.get("translation_of", None) language = data.get("language", None) if not type_: raise BadRequest("Property '@type' is required") # Disable CSRF protection if "IDisableCSRFProtection" in dir(plone.protect.interfaces): alsoProvides(self.request, plone.protect.interfaces.IDisableCSRFProtection) try: obj = create(self.context, type_, id_=id_, title=title) except Unauthorized as exc: self.request.response.setStatus(403) return dict(error=dict(type="Forbidden", message=str(exc))) except BadRequest as exc: self.request.response.setStatus(400) return dict(error=dict(type="Bad Request", message=str(exc))) # Acquisition wrap temporarily to satisfy things like vocabularies # depending on tools temporarily_wrapped = False if IAcquirer.providedBy(obj) and not safe_hasattr(obj, "aq_base"): obj = obj.__of__(self.context) temporarily_wrapped = True # Update fields deserializer = queryMultiAdapter((obj, self.request), IDeserializeFromJson) if deserializer is None: self.request.response.setStatus(501) return dict( error=dict(message="Cannot deserialize type {}".format(obj.portal_type)) ) try: deserializer(validate_all=True, create=True) except DeserializationError as e: self.request.response.setStatus(400) return dict(error=dict(type="DeserializationError", message=str(e))) if temporarily_wrapped: obj = aq_base(obj) if not getattr(deserializer, "notifies_create", False): notify(ObjectCreatedEvent(obj)) obj = add(self.context, obj, rename=not bool(id_)) # Link translation given the translation_of property if PAM_INSTALLED and PLONE5: from plone.app.multilingual.interfaces import ( IPloneAppMultilingualInstalled, ) # noqa from plone.app.multilingual.interfaces import ITranslationManager if ( IPloneAppMultilingualInstalled.providedBy(self.request) and translation_of and language ): source = self.get_object(translation_of) if source: manager = ITranslationManager(source) manager.register_translation(language, obj) self.request.response.setStatus(201) self.request.response.setHeader("Location", obj.absolute_url()) # imio.restapi, begin changes, manage returning full object or summary return_full_object = data.get( "return_fullobject", get_return_fullobject_after_creation_default()) if return_full_object: serializer = queryMultiAdapter((obj, self.request), ISerializeToJson) else: serializer = queryMultiAdapter((obj, self.request), ISerializeToJsonSummary) serialized_obj = serializer() # imio.restapi, end changes, manage returning full object or summary # HypermediaBatch can't determine the correct canonical URL for # objects that have just been created via POST - so we make sure # to set it here serialized_obj["@id"] = obj.absolute_url() return serialized_obj
def test_get_translated_languages(self): translated_languages = \ ITranslationManager(self.a_ca).get_translated_languages() self.assertEqual(translated_languages, ['ca'])
def test_has_translation(self): translation_manager = ITranslationManager(self.a_ca) self.assertTrue(translation_manager.has_translation('ca')) self.assertFalse(translation_manager.has_translation('es'))
def get_translation(self, language): manager = ITranslationManager(self.context) return manager.get_translation(language)
def test_get_restricted_translation(self): restricted_translations = \ ITranslationManager(self.a_ca).get_restricted_translations() self.assertEqual(restricted_translations, {'ca': self.a_ca})
class BabelUtils(BrowserView): def __init__(self, context, request): super(BabelUtils, self).__init__(context, request) portal_state = getMultiAdapter((context, request), name="plone_portal_state") self.portal_url = portal_state.portal_url() # If there is any translation_info lets use it try: self.group = TranslationManager(request.translation_info['tg']) except AttributeError: self.group = ITranslationManager(self.context) def getGroup(self): return self.group def getTranslatedLanguages(self): return self.group.get_translated_languages() def getPortal(self): portal_url = getToolByName(self.context, 'portal_url') return portal_url def objToTranslate(self): return self.context def gtenabled(self): registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema, prefix="plone") key = settings.google_translation_key return key is not None and len(key.strip()) > 0 def languages(self): """ Deprecated """ context = aq_inner(self.context) ls = LanguageSelector(context, self.request, None, None) ls.update() results = ls.languages() supported_langs = [v['code'] for v in results] missing = set([str(c) for c in supported_langs]) lsv = LanguageSelectorViewlet(context, self.request, None, None) translations = lsv._translations(missing) # We want to see the babel_view append_path = ('', 'babel_view',) non_viewable = set() for data in results: code = str(data['code']) data['translated'] = code in translations.keys() appendtourl = '/'.join(append_path) if data['translated']: trans, direct, has_view_permission = translations[code] if not has_view_permission: # shortcut if the user cannot see the item non_viewable.add((data['code'])) continue data['url'] = trans.absolute_url() + appendtourl else: non_viewable.add((data['code'])) # filter out non-viewable items results = [r for r in results if r['code'] not in non_viewable] return results def translated_languages(self): context = aq_inner(self.context) tool = getToolByName(context, 'portal_languages', None) checkPermission = getSecurityManager().checkPermission translations = self.group.get_translations() translated_info =\ [dict(code=key, info=tool.getAvailableLanguageInformation()[key], obj=translations[key]) for key in translations] default_language = tool.getDefaultLanguage() translated_shown = [] for lang_info in translated_info: # Mark the default language as the first translation shown if lang_info['code'] == default_language: lang_info['isDefault'] = True else: lang_info['isDefault'] = False # Remove the translation of the content currently being # translated In case it's temporal we show as language is not # already set on AT portal_factory = getToolByName( self.context, 'portal_factory', None ) context_language = ILanguage(context).get_language() if (portal_factory is None or not portal_factory.isTemporary(self.context)) \ and lang_info['code'] == context_language: continue # Remove the translation in case the translator user does not # have permissions over it has_view_permission =\ bool(checkPermission('View', lang_info['obj'])) if not has_view_permission: continue translated_shown.append(lang_info) return translated_shown def current_language_name(self): """ Get the current language native name """ adapted = ILanguage(self.context) lang_code = adapted.get_language() util = getUtility(IContentLanguageAvailability) data = util.getLanguages(True) lang_info = data.get(lang_code) return lang_info.get('native', None) or lang_info.get('name') def max_nr_of_buttons(self): registry = getUtility(IRegistry) settings = registry.forInterface(IMultiLanguageExtraOptionsSchema, prefix="plone") return settings.buttons_babel_view_up_to_nr_translations
def create_video_translation(self, video, language): ITranslationManager(video).add_translation(language) translated_video = ITranslationManager(video).get_translation(language) translated_video = self.copy_fields_to_translation(video, translated_video) return translated_video
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 translateArtists(language="en"): import plone.api import transaction from plone.app.multilingual.interfaces import ITranslationManager container_path = "/nl/online-archief/kunstenaars" with plone.api.env.adopt_user(username="******"): container = plone.api.content.get(path=container_path) total = len(list(container)) curr = 0 for _id in list(container): curr += 1 print "Translating Person %s / %s to '%s'" %(curr, total, language) person = container[_id] if not ITranslationManager(person).has_translation(language): ITranslationManager(person).add_translation(language) person_translated = ITranslationManager(person).get_translation(language) person_translated.title = person.title person_translated.firstname = person.firstname person_translated.lastname = person.lastname person_translated.nationality = person.nationality person_translated.year = person.year person_translated.reindexObject() transaction.get().commit() print "Translation added for Person '%s'" %(person.title) else: print "Person '%s' already has a translation to '%s'" %(person.title, language) return True