コード例 #1
0
    def update(self):
        self.portal_state = getMultiAdapter((self.context, self.request), name=u'plone_portal_state')
        self.site_url = self.portal_state.portal_url()
        ls = LanguageSelector(self.context, self.request, self.view, self.manager)
        ls.update()
        results = ls.languages()
        translatable = ITranslatable(self.context, None)
        if translatable is not None:
            translations = translatable.getTranslations()
        else:
            translations = []

        for data in results:
            data['translated'] = data['code'] in translations
            if data['translated']:
                trans = translations[data['code']][0]
                state = getMultiAdapter((trans, self.request),
                        name='plone_context_state')
                data['url'] = state.view_url() + '?set_language=' + data['code']
            else:
                state = getMultiAdapter((self.context, self.request), name='plone_context_state')
                try:
                    data['url'] = state.view_url() + '?set_language=' + data['code']
                except AttributeError:
                    data['url'] = self.context.absolute_url() + '?set_language=' + data['code']
コード例 #2
0
ファイル: views.py プロジェクト: giacomos/silvuple
        def can_translate(context, language):
            """ Check if required parent translations are in place so that we can translate this item

            :return: True if the item can be translated
            """
            parent = aq_parent(context)

            if ISiteRoot.providedBy(parent):
                return True

            # Parent is a language base folder at plone site root
            if INavigationRoot.providedBy(parent):
                return True

            if ITranslatable.providedBy(parent):
                translatable = ITranslatable(parent)
            else:
                from logging import getLogger

                log = getLogger("silvuple.views.can_translate")
                log.info("Parent is not translatable: %s" % parent.absolute_url())
                return False

            translation = translatable.getTranslation(language)

            return translation is not None
コード例 #3
0
    def findLocationForTranslation(self, language):
        parent = aq_parent(aq_inner(self.context))
        trans_parent = ITranslatable(parent, None)
        if trans_parent is None:
            return parent

        return trans_parent.getTranslation(language) or parent
コード例 #4
0
ファイル: utils.py プロジェクト: mvaled/Products.LinguaPlone
    def findLocationForTranslation(self, language):
        parent = aq_parent(aq_inner(self.context))
        trans_parent = ITranslatable(parent, None)
        if trans_parent is None:
            return parent

        return trans_parent.getTranslation(language) or parent
コード例 #5
0
    def languages(self):
        current_language = unicode(getMultiAdapter((self.context, self.request), name='plone_portal_state').language())
        languages = LanguageSelector.languages(self)
        translatable = ITranslatable(self.context, None)
        if translatable is not None:
            translations = translatable.getTranslations()
        else:
            translations = []

        results = []
        for data in languages:
            data['translated'] = data['code'] in translations
            if data['code'] == current_language or not data['translated']:
                continue
            
            if data['translated']:
                trans = translations[data['code']][0]
                state = getMultiAdapter((trans, self.request),
                        name='plone_context_state')
                data['url'] = state.view_url() + '?set_language=' + data['code']
            else:
                state = getMultiAdapter((self.context, self.request),
                        name='plone_context_state')
                try:
                    data['url'] = state.view_url() + '?set_language=' + data['code']
                except AttributeError:
                    data['url'] = self.context.absolute_url() + '?set_language=' + data['code']
            
            results.append(data)

        return results
コード例 #6
0
ファイル: viewlets.py プロジェクト: syslabcom/osha.fop
    def get_additional_translations(self):
        """
        Return translations for the current context which aren't
        available from the language selection drop down

        {"tr":("Turkish", "http://url",) ...}
        """
        context = self.context
        portal_langs = [i["code"] for i in self.languages()]

        translatable = ITranslatable(context, None)
        if translatable is not None:
            translations = translatable.getTranslations()
        else:
            translations = {}

        additional_translations = {}
        portal_state = queryMultiAdapter((context, self.request),
                                         name=u'plone_portal_state')
        lang_names = portal_state.locale().displayNames.languages
        lang_codes = [i for i in translations.keys() if i not in portal_langs
            and i != ""]
        can_edit = getSecurityManager().checkPermission(
                permissions.ModifyPortalContent,
                context
                )

        for lang_code in lang_codes:
            is_published = translations[lang_code][1] == "published"
            if can_edit or is_published:
                additional_translations[lang_code] = \
                    (lang_names[lang_code],
                     translations[lang_code][0].absolute_url(),)
        return additional_translations
コード例 #7
0
    def languages(self):
        results = LanguageSelector.languages(self)
        
        # On the main portal, we want to be able to filter out unwanted
        # languages needes for subsites
        oshaview = getMultiAdapter((self.context, self.request), name='oshaview')
        subsite_path = oshaview.subsiteRootPath()
        potential_subsite = self.context.restrictedTraverse(subsite_path)
            
        # get the potentially present question- and country-id
        # Due to apache rewriting, we cannot use PATH_INFO, but must contruct the path manually
        # first, get the URL and snip the SERVER_URL off
        path = self.request.get('URL')[len(self.request.get('SERVER_URL'))+1:]
        # then pre-pend VirtualURL components if present
        elems = [x for x in self.request.get('VirtualRootPhysicalPath', [''])] + path.split('/')
        # join it to a path
        virtual_path = '/'.join(elems)
        # get the context's path
        context_path = '/'.join(self.context.getPhysicalPath())
        # just an extra test, as the following expression should always be true
        if virtual_path.startswith(context_path):
            question_path = virtual_path[len(context_path):]
        else:
            question_path = ''

        group_by = 'group_by' in self.request and '&group_by=' + \
            self.request.get('group_by') or ''

        # for translatable content, directly link to the translated objects
        translatable = ITranslatable(self.context, None)
        if translatable is not None:
            translations = translatable.getTranslations()
        else:
            translations = []

        for data in results:
            data['translated'] = data['code'] in translations
            if data['translated']:
                trans = translations[data['code']][0]
                state = getMultiAdapter((trans, self.request),
                        name='plone_context_state')
                data['url'] = state.view_url() + question_path + \
                    '?set_language=' + data['code'] + group_by
            else:
                state = getMultiAdapter((self.context, self.request),
                        name='plone_context_state')
                try:
                    data['url'] = state.view_url() + '/not_available_lang?set_language=' + data['code']
                except AttributeError:
                    data['url'] = self.context.absolute_url() + '/not_available_lang?set_language=' + data['code']

        return results
コード例 #8
0
    def index_object(self, documentId, obj, treshold=None):
        """Index the object"""
        if not ITranslatable.providedBy(obj):
            if IIndexableObjectWrapper.providedBy(obj):
                # wrapped object in `plone.indexer`
                wrapped = getattr(obj, '_IndexableObjectWrapper__object', None)
                # XXX: the rest can probably go now...
                # Wrapper doesn't proxy __implements__
                if wrapped is None:
                    wrapped = getattr(obj, '_IndexableObjectWrapper__ob', None)
                # Older CMFPlone
                if wrapped is None:
                    wrapped = getattr(obj, '_obj', None)
                if wrapped is None:
                    return 0
                obj = wrapped

        try:
            language = obj.Language
            if callable(language):
                language = language()
        except AttributeError:
            return 0

        if ITranslatable.providedBy(obj):
            canonical = obj.getCanonical()
            # Gracefully deal with broken references
            if canonical is None:
                return 0
            cid = canonical.UID()
        else:
            # Also index non-translatable content, otherwise
            # LinguaPlone only shows translatable content.
            # This assumes a catalog documentId will never
            # be equal to a UID.
            cid = documentId

        if documentId not in self._unindex:
            self._length.change(1)
        else:
            self._remove(self._unindex[documentId])

        main, sub = splitLanguage(language)
        entry = IndexEntry(documentId, main, sub, cid)
        self._insert(entry)
        self._unindex[documentId] = entry
        self._sortindex[documentId] = str(entry)

        return 1
コード例 #9
0
def processForm(self, data=1, metadata=0, REQUEST=None, values=None):
    """Process the schema looking for data in the form."""
    is_new_object = self.checkCreationFlag()

    BaseObject.processForm(self, data, metadata, REQUEST, values)
    if config.AUTO_NOTIFY_CANONICAL_UPDATE:
        if self.isCanonical():
            self.invalidateTranslations()

    if self._at_rename_after_creation and is_new_object:
        new_id = self._renameAfterCreation(
            check_auto_id=not not self.REQUEST.form.get('id'))
    else:
        new_id = None

    if shasattr(self, '_lp_default_page'):
        delattr(self, '_lp_default_page')
        language = self.getLanguage()
        canonical = self.getCanonical()
        parent = aq_parent(aq_inner(self))
        if ITranslatable.providedBy(parent):
            if not parent.hasTranslation(language):
                parent.addTranslation(language)
                translation_parent = parent.getTranslation(language)
                translation_parent.processForm(values=dict(title=self.Title()))
                translation_parent.setDescription(self.Description())
                parent = translation_parent

            if ISelectableBrowserDefault.providedBy(parent) and new_id:
                parent.setDefaultPage(new_id)

    if shasattr(self, '_lp_outdated'):
        delattr(self, '_lp_outdated')
コード例 #10
0
 def _get_trans(self, ob):
     if not HAVE_LP or not ITranslatable.providedBy(ob):
         return ''
     can = ob.getCanonical()
     if can != ob:
         return can.UID()
     return ''
コード例 #11
0
ファイル: I18NBaseObject.py プロジェクト: dtgit/dtedu
    def setLanguage(self, value, **kwargs):
        """Sets the language code.

        When changing the language in a translated folder structure,
        we try to move the content to the existing language tree.
        """
        translation = self.getTranslation(value)
        if self.hasTranslation(value):
            if translation == self:
                return
            else:
                raise AlreadyTranslated, translation.absolute_url()
        self.getField('language').set(self, value, **kwargs)

        # If we are called during a schema update we should not be deleting
        # any language relations.
        req = getattr(self, 'REQUEST', None)
        if shasattr(req, 'get'):
            if req.get('SCHEMA_UPDATE', None) is not None:
                return

        if not value:
            self.deleteReferences(config.RELATIONSHIP)

        parent = aq_parent(aq_inner(self))
        if ITranslatable.providedBy(parent):
            new_parent = parent.getTranslation(value) or parent
            if new_parent != parent:
                info = parent.manage_cutObjects([self.getId()])
                new_parent.manage_pasteObjects(info)
        self.reindexObject()
        self.invalidateTranslationCache()
コード例 #12
0
    def content(self):
        """
        Returns the content object or None if it does not exist.
        """

        if not self.data.content:
            return None

        portal_path = getToolByName(self.context, 'portal_url').getPortalPath()
        item = self.context.unrestrictedTraverse(
            str(portal_path + self.data.content), None)
        if item is None:
            return None

        if LINGUAPLONE_SUPPORT:
            tool = getToolByName(self.context, 'portal_languages', None)
            if tool is not None and ITranslatable.providedBy(item):
                lang = tool.getLanguageBindings()[0]
                xlate_item = item.getTranslation(lang)
                if xlate_item is not None:
                    item = xlate_item

        if not getSecurityManager().checkPermission('View', item):
            return None
        return item
コード例 #13
0
def processForm(self, data=1, metadata=0, REQUEST=None, values=None):
    """Process the schema looking for data in the form."""
    is_new_object = self.checkCreationFlag()
    
    BaseObject.processForm(self, data, metadata, REQUEST, values)
    if config.AUTO_NOTIFY_CANONICAL_UPDATE:
        if self.isCanonical():
            self.invalidateTranslations()

    if self._at_rename_after_creation and is_new_object:
        new_id = self._renameAfterCreation(check_auto_id=not not self.REQUEST.form.get('id'))
    else:
        new_id = None

    if shasattr(self, '_lp_default_page'):
        delattr(self, '_lp_default_page')
        language = self.getLanguage()
        canonical = self.getCanonical()
        parent = aq_parent(aq_inner(self))
        if ITranslatable.providedBy(parent):
            if not parent.hasTranslation(language):
                parent.addTranslation(language)
                translation_parent = parent.getTranslation(language)
                translation_parent.processForm(
                        values=dict(title=self.Title()))
                translation_parent.setDescription(self.Description())
                parent = translation_parent

            if ISelectableBrowserDefault.providedBy(parent) and new_id:
                parent.setDefaultPage(new_id)

        
    if shasattr(self, '_lp_outdated'):
        delattr(self, '_lp_outdated')
コード例 #14
0
    def items(self):
        if not ITranslatable.providedBy(self.context):

            def plain_context(info):
                info["has_translation"] = False

            updater = plain_context
        else:

            def translatable_context(info):
                trans = self.context.getTranslation(info["code"])
                if trans is None:
                    info["has_translation"] = False
                else:
                    info["has_translation"] = True
                    state = getMultiAdapter((trans, self.request),
                                            name='plone_context_state')
                    info["url"] = state.view_url()

            updater = translatable_context

        for lang in self.languages:
            updater(lang)

        return self.languages
コード例 #15
0
    def content(self):
        """
        Returns the content object or None if it does not exist.
        """

        if not self.data.content:
            return None

        portal_path = getToolByName(self.context, 'portal_url').getPortalPath()
        item = self.context.unrestrictedTraverse(
            str(portal_path + self.data.content),
            None
        )
        if item is None:
            return None

        if LINGUAPLONE_SUPPORT:
            tool = getToolByName(self.context, 'portal_languages', None)
            if tool is not None and ITranslatable.providedBy(item):
                lang = tool.getLanguageBindings()[0]
                xlate_item = item.getTranslation(lang)
                if xlate_item is not None:
                    item = xlate_item

        if not getSecurityManager().checkPermission('View', item):
            return None
        return item
コード例 #16
0
def find_content_with_wrong_language(content):
    """log non-default content with different languages than their parents
    Used to make sure we cleaned up everything.
    In part stolen and adapted from
    plone.app.multilingual.browser.migrator.moveContentToProperRLF.findContent
    """
    # only handle portal content
    from plone.dexterity.interfaces import IDexterityContent
    from Products.Archetypes.interfaces import IBaseObject
    from Acquisition import aq_base
    from Acquisition import aq_parent
    try:
        from Products.LinguaPlone.interfaces import ITranslatable
    except ImportError:
        from plone.app.multilingual.interfaces import ITranslatable

    if not IDexterityContent.providedBy(content)\
            and not IBaseObject.providedBy(content)\
            and not IPloneSiteRoot.providedBy(content):
        return
    if hasattr(aq_base(content), 'objectIds'):
        for id in content.objectIds():
            find_content_with_wrong_language(getattr(content, id))
    if ITranslatable.providedBy(content):
        # The content parent has the same language?
        if not IPloneSiteRoot.providedBy(aq_parent(content)) \
           and aq_parent(content).Language() != content.Language():
            log.info('Obj %s (%s) not same language as parent (%s)' %
                     (content.absolute_url_path(), content.Language(),
                      aq_parent(content).Language()))  # noqa: E501
コード例 #17
0
 def find_endpoint(self, obj, lang, types_to_list):
     if not (IFolder.providedBy(obj) or IPloneSiteRoot.providedBy(obj)):
         return obj
     contents = obj.contentIds()
     # TODO: make list reversable
     for cid in contents:
         child = obj[cid]
         # try to get translation if LinguaPlone is installed, child
         # is translatable and child language does not match lang
         if LINGUA_PLONE_INSTALLED:
             if ITranslatable.providedBy(child):
                 child_lang = child.Language()
                 # child lang can be empty string, only try to
                 # translate if explicit lang
                 if child_lang and child_lang != lang:
                     translation = child.getTranslation(lang)
                     if not translation:
                         continue  # ...with next obj in folder
                     child = translation
         # only traverse to allowed objects
         allowed = self.permitted(context=child, permission=VIEW_PERMISSION)
         if not allowed:
             continue
         # only traverse to objects listed in typesToList
         if child.portal_type not in types_to_list:
             continue
         # we've found a published object, which can be used as
         # possible endpoint, except it has 'traverse_view' enabled
         obj = child
         if child.defaultView() == "traverse_view":
             obj = self.find_endpoint(child, lang, types_to_list)
         break
     return obj
コード例 #18
0
ファイル: atcttestcase.py プロジェクト: Vinsurya/Plone
 def test_implementsTranslateable(self):
     # lingua plone is adding the ITranslatable interface to all types
     if not HAS_LINGUA_PLONE:
         return
     else:
         from Products.LinguaPlone.interfaces import ITranslatable
         self.assertTrue(ITranslatable.providedBy(self._ATCT))
         self.assertTrue(verifyObject(ITranslatable, self._ATCT))
コード例 #19
0
    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:
                    obj.addTranslationReference(canonical)
                except AlreadyTranslated:
                    from logging import getLogger
                    log = getLogger(__name__)
                    log.info("Object already translated: {}".format(obj.absolute_url()))
コード例 #20
0
    def __call__(self, context):
        self.context = context
        # return all items in the current folder that are translatable
        terms = [SimpleTerm(id, title=u'%s (%s)' % (unicode(obj.Title(),
            'utf-8'), id)) for id, obj in context.objectItems()
            if ITranslatable.providedBy(obj)]

        return SimpleVocabulary(terms)
コード例 #21
0
 def test_implementsTranslateable(self):
     # lingua plone is adding the ITranslatable interface to all types
     if not HAS_LINGUA_PLONE:
         return
     else:
         from Products.LinguaPlone.interfaces import ITranslatable
         self.assertTrue(ITranslatable.providedBy(self._ATCT))
         self.assertTrue(verifyObject(ITranslatable, self._ATCT))
コード例 #22
0
ファイル: I18NBaseObject.py プロジェクト: dtgit/dtedu
 def addTranslation(self, language, *args, **kwargs):
     """Adds a translation."""
     canonical = self.getCanonical()
     parent = aq_parent(aq_inner(self))
     if ITranslatable.providedBy(parent):
         parent = parent.getTranslation(language) or parent
     if self.hasTranslation(language):
         translation = self.getTranslation(language)
         raise AlreadyTranslated, translation.absolute_url()
     id = canonical.getId()
     while not parent.checkIdAvailable(id):
         id = '%s-%s' % (id, language)
     kwargs[config.KWARGS_TRANSLATION_KEY] = canonical
     if kwargs.get('language', None) != language:
         kwargs['language'] = language
     o = _createObjectByType(self.portal_type, parent, id, *args, **kwargs)
     # If there is a custom factory method that doesn't add the
     # translation relationship, make sure it is done now.
     if o.getCanonical() != canonical:
         o.addTranslationReference(canonical)
     self.invalidateTranslationCache()
     # Copy over the language independent fields
     schema = canonical.Schema()
     independent_fields = schema.filterFields(languageIndependent=True)
     for field in independent_fields:
         accessor = field.getEditAccessor(canonical)
         if not accessor:
             accessor = field.getAccessor(canonical)
         data = accessor()
         translation_mutator = getattr(o, field.translation_mutator)
         translation_mutator(data)
     # If this is a folder, move translated subobjects aswell.
     if self.isPrincipiaFolderish:
         moveids = []
         for obj in self.objectValues():
             if ITranslatable.providedBy(obj) and \
                        obj.getLanguage() == language:
                 lockable = ILockable(obj, None)
                 if lockable is not None and lockable.can_safely_unlock():
                     lockable.unlock()
                 moveids.append(obj.getId())
         if moveids:
             o.manage_pasteObjects(self.manage_cutObjects(moveids))
     o.reindexObject()
     if isDefaultPage(canonical, self.REQUEST):
         o._lp_default_page = True
コード例 #23
0
ファイル: selector.py プロジェクト: syslabcom/recensio.policy
    def _translations(self, missing):
        # Figure out the "closest" translation in the parent chain of the
        # context. We stop at both an INavigationRoot or an ISiteRoot to look
        # for translations.
        # Exceptions: 1) If the object does not implement ITranslatable (= not
        # LP-aware) or
        # 2) if the object is set to be neutral
        # then return this object and don't look for a translation.
        context = aq_inner(self.context)
        translations = {}
        chain = aq_chain(context)
        first_pass = True
        _checkPermission = getSecurityManager().checkPermission
        for item in chain:
            if ISiteRoot.providedBy(item) \
                or not ITranslatable.providedBy(item) \
                or not item.Language():
                # We have a site root, which works as a fallback
                has_view_permission = bool(_checkPermission('View', item))
                for c in missing:
                    translations[c] = (item, first_pass, has_view_permission)
                break

            translatable = ITranslatable(item, None)
            if translatable is None:
                continue

            item_trans = item.getTranslations(review_state=False)
            for code, trans in item_trans.items():
                code = str(code)
                if code not in translations:
                    # make a link to a translation only if the user
                    # has view permission
                    has_view_permission = bool(_checkPermission('View', trans))
                    if (not INavigationRoot.providedBy(item)
                            and not has_view_permission):
                        continue
                    # If we don't yet have a translation for this language
                    # add it and mark it as found
                    translations[code] = (trans, first_pass,
                                          has_view_permission)
                    missing = missing - set((code, ))

            if len(missing) <= 0:
                # We have translations for all
                break
            if INavigationRoot.providedBy(item):
                # Don't break out of the navigation root jail
                has_view_permission = bool(_checkPermission('View', item))
                for c in missing:
                    translations[c] = (item, False, has_view_permission)
                break
            first_pass = False
        # return a dict of language code to tuple. the first tuple element is
        # the translated object, the second argument indicates wether the
        # translation is a direct translation of the context or something from
        # higher up the translation chain
        return translations
コード例 #24
0
 def alternate_i18n(self):
     """ Return available translations if LinguaPlone is available """
     if LINGUA_PLONE and ITranslatable.providedBy(self.context):
         translations = self.context.getTranslations(review_state=False)
         if self.context.Language() in translations:
             del translations[self.context.Language()]
         return translations
     else:
         return []
コード例 #25
0
    def __call__(self):
        obj = self.event.object

        if hasLinguaPloneInstalled and ITranslatable.providedBy(obj):
            translations = obj.getTranslations()
            if len(translations) > 1:
                for trans, _state in translations.values():
                    logging.info("*** PURGING VARNISH CACHE: %s",
                                 trans.absolute_url())
                    notify(Purge(trans))
コード例 #26
0
    def __call__(self):
        obj = self.event.object

        if hasLinguaPloneInstalled and ITranslatable.providedBy(obj):
            translations = obj.getTranslations()
            if len(translations) > 1:
                for trans, _state in translations.values():
                    logging.info("*** PURGING VARNISH CACHE: %s",
                                 trans.absolute_url())
                    notify(Purge(trans))
コード例 #27
0
    def isDefaultPage(self, obj):
        default_page = super(DefaultPage, self).getDefaultPage()
        if obj.getId() == default_page:
            return True

        if ITranslatable.providedBy(obj):
            for translation in obj.getTranslations(review_state=False).values():
                if translation.getId() == default_page:
                    return True

        return False
コード例 #28
0
    def _translations(self, missing):
        # Figure out the "closest" translation in the parent chain of the
        # context. We stop at both an INavigationRoot or an ISiteRoot to look
        # for translations. We do want to find something that is definitely
        # in the language the user asked for.
        context = aq_inner(self.context)
        translations = {}
        chain = aq_chain(context)
        first_pass = True
        _checkPermission = getSecurityManager().checkPermission
        for item in chain:
            if ISiteRoot.providedBy(item):
                # We have a site root, which works as a fallback
                has_view_permission = bool(_checkPermission('View', item))
                for c in missing:
                    translations[c] = (item, first_pass, has_view_permission)
                break

            translatable = ITranslatable(item, None)
            if translatable is None:
                continue

            item_trans = item.getTranslations(review_state=False)
            for code, trans in item_trans.items():
                code = str(code)
                if code not in translations:
                    # make a link to a translation only if the user
                    # has view permission
                    has_view_permission = bool(_checkPermission('View', trans))
                    if (not INavigationRoot.providedBy(item)
                            and not has_view_permission):
                        continue
                    # If we don't yet have a translation for this language
                    # add it and mark it as found
                    translations[code] = (trans, first_pass,
                                          has_view_permission)
                    missing = missing - set((code, ))

            if len(missing) <= 0:
                # We have translations for all
                break
            if INavigationRoot.providedBy(item):
                # Don't break out of the navigation root jail
                has_view_permission = bool(_checkPermission('View', item))
                for c in missing:
                    translations[c] = (item, False, has_view_permission)
                break
            first_pass = False
        # return a dict of language code to tuple. the first tuple element is
        # the translated object, the second argument indicates wether the
        # translation is a direct translation of the context or something from
        # higher up the translation chain
        return translations
コード例 #29
0
    def conversationCanonicalAdapterFactory(content): # pragma: no cover
        """Adapter factory to fetch the default conversation from annotations.
        Will create the conversation if it does not exist.

        This adapter will fetch and store all comments on the canonical object,
        so that comments will be shared across all translations.
        """
        if ITranslatable.providedBy(content):
            canonical = content.getCanonical()
            if canonical is not None:
                return conversationAdapterFactory(canonical)
        return conversationAdapterFactory(content)
コード例 #30
0
    def isDefaultPage(self, obj):
        default_page = super(DefaultPage, self).getDefaultPage()
        if obj.getId() == default_page:
            return True

        if ITranslatable.providedBy(obj):
            for translation in obj.getTranslations(
                review_state=False).values():
                if translation.getId() == default_page:
                    return True

        return False
コード例 #31
0
    def conversationCanonicalAdapterFactory(content):  # pragma: no cover
        """Adapter factory to fetch the default conversation from annotations.
        Will create the conversation if it does not exist.

        This adapter will fetch and store all comments on the canonical object,
        so that comments will be shared across all translations.
        """
        if ITranslatable.providedBy(content):
            canonical = content.getCanonical()
            if canonical is not None:
                return conversationAdapterFactory(canonical)
        return conversationAdapterFactory(content)
コード例 #32
0
ファイル: views.py プロジェクト: spanktar/silvuple
        def can_translate(context, language):
            """ Check if required parent translations are in place so that we can translate this item

            :return: True if the item can be translated
            """
            parent = context.aq_parent

            if ISiteRoot.providedBy(parent):
                return True

            # Parent is a language base folder at plone site root
            if INavigationRoot.providedBy(parent):
                return True

            if ITranslatable.providedBy(parent):
                translatable = ITranslatable(parent)
            else:
                raise RuntimeError("Not translatable parent: %s" % parent)

            translation = translatable.getTranslation(language)

            return translation is not None
コード例 #33
0
    def createTranslation(self, container, language, *args, **kwargs):
        context = aq_inner(self.context)
        canonical = context.getCanonical()
        portal_type = self.getTranslationPortalType(container, language)
        new_id = kwargs.pop(
            'id', self.generateId(container, canonical.getId(), language))
        kwargs["language"] = language
        translation = _createObjectByType(portal_type, container, new_id,
                                          *args, **kwargs)

        # If there is a custom factory method that doesn't add the
        # translation relationship, make sure it is done now.
        if translation.getCanonical() != canonical:
            translation.addTranslationReference(canonical)

        # THIS IS THE LINE WE NEED TO CUSTOMIZE
        OSHALanguageIndependentFields(canonical).copyFields(translation)

        if isDefaultPage(aq_parent(aq_inner(canonical)), canonical):
            translation._lp_default_page = True

        # If this is a folder, move translated subobjects aswell.
        if context.isPrincipiaFolderish:
            moveids = []
            for obj in context.values():
                translator = ITranslatable(obj, None)
                if translator is not None \
                   and translator.getLanguage() == language:
                    lockable = ILockable(obj, None)
                    if lockable is not None and lockable.can_safely_unlock():
                        lockable.unlock()
                    moveids.append(obj.getId())
            if moveids:
                info = context.manage_cutObjects(moveids)
                translation.manage_pasteObjects(info)

        return translation
コード例 #34
0
    def createTranslation(self, container, language, *args, **kwargs):
        context = aq_inner(self.context)
        canonical = context.getCanonical()
        portal_type = self.getTranslationPortalType(container, language)
        new_id = kwargs.pop(
            'id', self.generateId(container, canonical.getId(), language))
        kwargs["language"] = language
        translation = _createObjectByType(portal_type, container,
                                          new_id, *args, **kwargs)

        # If there is a custom factory method that doesn't add the
        # translation relationship, make sure it is done now.
        if translation.getCanonical() != canonical:
            translation.addTranslationReference(canonical)

        # THIS IS THE LINE WE NEED TO CUSTOMIZE
        OSHALanguageIndependentFields(canonical).copyFields(translation)

        if isDefaultPage(aq_parent(aq_inner(canonical)), canonical):
            translation._lp_default_page = True

        # If this is a folder, move translated subobjects aswell.
        if context.isPrincipiaFolderish:
            moveids = []
            for obj in context.values():
                translator = ITranslatable(obj, None)
                if translator is not None \
                   and translator.getLanguage() == language:
                    lockable = ILockable(obj, None)
                    if lockable is not None and lockable.can_safely_unlock():
                        lockable.unlock()
                    moveids.append(obj.getId())
            if moveids:
                info = context.manage_cutObjects(moveids)
                translation.manage_pasteObjects(info)

        return translation
コード例 #35
0
    def processForm(self, data=1, metadata=0, REQUEST=None, values=None):
        """Process the schema looking for data in the form."""
        is_new_object = self.checkCreationFlag()
        BaseObject.processForm(self,
                               data=data,
                               metadata=metadata,
                               REQUEST=REQUEST,
                               values=values)
        # LP specific bits
        if config.AUTO_NOTIFY_CANONICAL_UPDATE:
            if self.isCanonical():
                self.invalidateTranslations()

        # Check if an explicit id has been passed
        explicit_id = False
        if REQUEST is None:
            REQUEST = getattr(self, 'REQUEST', None)

        if REQUEST is not None:
            if 'id' in REQUEST.form and REQUEST.form.get('id'):
                explicit_id = True

        if values is not None:
            if 'id' in values and values.get('id'):
                explicit_id = True

        if (is_new_object and not explicit_id
                and self._at_rename_after_creation):
            # Renames an object like its normalized title
            self._renameAfterCreation(check_auto_id=True)

        if shasattr(self, '_lp_default_page'):
            delattr(self, '_lp_default_page')
            language = self.Language()
            parent = aq_parent(aq_inner(self))
            if ITranslatable.providedBy(parent) and parent.Language() != '':
                if not parent.hasTranslation(language):
                    parent.addTranslation(language)
                    translation_parent = parent.getTranslation(language)
                    translation_parent.processForm(values=dict(
                        title=self.Title()))
                    translation_parent.setDescription(self.Description())
                    parent = translation_parent

                if ISelectableBrowserDefault.providedBy(parent):
                    parent.setDefaultPage(self.getId())

        if shasattr(self, '_lp_outdated'):
            delattr(self, '_lp_outdated')
コード例 #36
0
ファイル: views.py プロジェクト: zmijunkie/silvuple
        def can_translate(context, language):
            """ Check if required parent translations are in place so that we can translate this item

            :return: True if the item can be translated

            """

            assert context is not None

            parent = aq_parent(context)

            if ISiteRoot.providedBy(parent):
                return True

            # Parent is a language base folder at plone site root
            if INavigationRoot.providedBy(parent):
                return True

            if ITranslatable.providedBy(parent):
                translatable = ITranslatable(parent)
            else:
                from logging import getLogger
                log = getLogger('silvuple.views.can_translate')
                if parent:
                    log.info('Parent is not translatable: %s' %
                             parent.absolute_url())
                else:
                    log.error(
                        'Cannot translate language: %s, no parent for %s' %
                        (language, context.absolute_url()))

                return False

            translation = translatable.getTranslation(language)

            return translation is not None
コード例 #37
0
ファイル: I18NBaseObject.py プロジェクト: dtgit/dtedu
    def defaultLanguage(self):
        """Returns the initial default language."""
        parent = aq_parent(aq_inner(self))
        if ITranslatable.providedBy(parent):
            language = parent.Language()
            if language:
                return parent.Language()

        language_tool = getToolByName(self, 'portal_languages', None)
        if language_tool:
            if language_tool.startNeutral():
                return ''
            else:
                return language_tool.getPreferredLanguage()
        else:
            return LANGUAGE_DEFAULT
コード例 #38
0
    def defaultLanguage(self):
        """Returns the initial default language."""
        parent = aq_parent(aq_inner(self))
        if getattr(parent, 'portal_type', None) == 'TempFolder':
            # We have factory tool
            parent = aq_parent(aq_parent(parent))
        if ITranslatable.providedBy(parent):
            return parent.Language()

        language_tool = getToolByName(self, 'portal_languages', None)
        if language_tool:
            if language_tool.startNeutral():
                return ''
            else:
                return language_tool.getPreferredLanguage()
        else:
            return LANGUAGE_DEFAULT
コード例 #39
0
    def processForm(self, data=1, metadata=0, REQUEST=None, values=None):
        """Process the schema looking for data in the form."""
        is_new_object = self.checkCreationFlag()
        BaseObject.processForm(self, data=data, metadata=metadata,
                               REQUEST=REQUEST, values=values)
        # LP specific bits
        if config.AUTO_NOTIFY_CANONICAL_UPDATE:
            if self.isCanonical():
                self.invalidateTranslations()

        # Check if an explicit id has been passed
        explicit_id = False
        if REQUEST is None:
            REQUEST = getattr(self, 'REQUEST', None)

        if REQUEST is not None:
            if 'id' in REQUEST.form and REQUEST.form.get('id'):
                explicit_id = True

        if values is not None:
            if 'id' in values and values.get('id'):
                explicit_id = True

        if (is_new_object and not explicit_id and
            self._at_rename_after_creation):
            # Renames an object like its normalized title
            self._renameAfterCreation(check_auto_id=True)

        if shasattr(self, '_lp_default_page'):
            delattr(self, '_lp_default_page')
            language = self.Language()
            parent = aq_parent(aq_inner(self))
            if ITranslatable.providedBy(parent) and parent.Language() != '':
                if not parent.hasTranslation(language):
                    parent.addTranslation(language)
                    translation_parent = parent.getTranslation(language)
                    translation_parent.processForm(
                            values=dict(title=self.Title()))
                    translation_parent.setDescription(self.Description())
                    parent = translation_parent

                if ISelectableBrowserDefault.providedBy(parent):
                    parent.setDefaultPage(self.getId())

        if shasattr(self, '_lp_outdated'):
            delattr(self, '_lp_outdated')
コード例 #40
0
 def findContent(self, content, depth):
     # only handle portal content
     if not getattr(content, "portal_type", None):
         logger.warning("SKIP non-portal content %s (%s)" % (content.absolute_url(), content.meta_type))
         return
     if hasattr(aq_base(content), "objectIds") and content.portal_type not in self.blacklist:
         for id in content.objectIds():
             self.findContent(getattr(content, id), depth + 1)
     while len(self.content_tree) < depth + 1:
         self.content_tree.append([])
     if ITranslatable.providedBy(content):
         # The content parent has the same language?
         if (
             not IPloneSiteRoot.providedBy(aq_parent(content))
             and aq_parent(content).Language() != content.Language()
         ):
             self.content_tree[depth].append(content)
コード例 #41
0
    def defaultLanguage(self):
        """Returns the initial default language."""
        parent = aq_parent(aq_inner(self))
        if getattr(parent, 'portal_type', None) == 'TempFolder':
            # We have factory tool
            parent = aq_parent(aq_parent(parent))
        if ITranslatable.providedBy(parent):
            return parent.Language()

        language_tool = getToolByName(self, 'portal_languages', None)
        if language_tool:
            if language_tool.startNeutral():
                return ''
            else:
                return language_tool.getPreferredLanguage()
        else:
            return LANGUAGE_DEFAULT
コード例 #42
0
    def content(self):
        """
        Returns the content object or None if it does not exist.
        """

        if not self.data.content:
            return None

        portal_path = getToolByName(self.context, "portal_url").getPortalPath()
        item = self.context.restrictedTraverse(str(portal_path + self.data.content), None)

        if LINGUAPLONE_SUPPORT:
            tool = getToolByName(self.context, "portal_languages", None)
            if tool is not None and ITranslatable.providedBy(item):
                lang = tool.getLanguageBindings()[0]
                item = item.getTranslation(lang) or item

        return item
コード例 #43
0
ファイル: migrator.py プロジェクト: vedantc98/Plone-test
 def findContent(self, content, depth):
     # only handle portal content
     if not IDexterityContent.providedBy(content)\
             and not IBaseObject.providedBy(content):
         logger.warning('SKIP non-portal content %s (%s)' % (
             content.absolute_url(), content.meta_type))
         return
     if hasattr(aq_base(content), 'objectIds')\
             and aq_base(content).portal_type not in self.blacklist:
         for id in content.objectIds():
             self.findContent(getattr(content, id), depth + 1)
     while len(self.content_tree) < depth + 1:
         self.content_tree.append([])
     if ITranslatable.providedBy(content):
         # The content parent has the same language?
         if not IPloneSiteRoot.providedBy(aq_parent(content)) \
            and aq_parent(content).Language() != content.Language():
             self.content_tree[depth].append(content)
コード例 #44
0
    def getSortedKeys(self, instance=None):
        """ returns a list of keys sorted accordingly to the

        selected sort method (may be unsorted if method = no sort)
        """
        sortMethod = self.getSortMethod()
        context = self
        if self.isLinguaPloneInstalled():
            from Products.LinguaPlone.interfaces import ITranslatable
            langtool = getToolByName(self, 'portal_languages')
            if instance and ITranslatable.providedBy(instance):
                lang = instance.getLanguage() or langtool.getPreferredLanguage(
                )
            else:
                lang = langtool.getPreferredLanguage()
            context = context.getTranslation(lang) or self

        keys = [term.getVocabularyKey() for term in context.contentValues()]

        if not hasattr(self, 'sortMethod'):
            # smooth upgrade from previous releases
            return keys

        if sortMethod == SORT_METHOD_LEXICO_KEYS:
            keys.sort()
            return keys

        if sortMethod == SORT_METHOD_LEXICO_VALUES:
            # returns keys sorted by lexicogarphic order of VALUES
            terms = context.contentValues()
            terms.sort(lambda x, y: cmp(x.getTermValue(), y.getTermValue()))
            return [term.getVocabularyKey() for term in terms]

        if sortMethod == SORT_METHOD_FOLDER_ORDER:
            try:
                contentListing = getMultiAdapter((context, context.REQUEST),
                                                 name=u'folderListing')()
            except ComponentLookupError:
                # still Plone 3 compatible
                contentListing = context.getFolderContents()
            return [term.getObject().getTermKey() for term in contentListing]

        # fallback
        return keys
コード例 #45
0
    def testRelocatorOfMisplacedContent(self):
        self.a_en = makeContent(self.portal, 'Folder', id='a_en')
        self.a_en.edit(language='en')
        self.a_1_1_ca = makeContent(self.a_en, 'Folder', id='a_1_1_ca')
        self.a_1_1_ca.edit(language='ca')
        self.a_2_1_en = makeContent(self.a_1_1_ca, 'Document', id='a_2_1_en')
        self.a_2_1_en.edit(language='en')
        self.a_2_2_ca = makeContent(self.a_1_1_ca, 'Document', id='a_2_2_ca')
        self.a_2_2_ca.edit(language='ca')
        self.a_1_2_en = makeContent(self.a_en, 'Folder', id='a_1_2_en')
        self.a_1_2_en.edit(language='en')

        self.b_ca = makeContent(self.portal, 'Folder', id='b_ca')
        self.b_ca.edit(language='ca')
        self.b_1_1_en = makeContent(self.b_ca, 'Folder', id='b_1_1_en')
        self.b_1_1_en.edit(language='en')
        self.b_2_1_en = makeContent(self.b_1_1_en, 'Document', id='b_2_1_en')
        self.b_2_1_en.edit(language='en')
        self.b_2_1_ca = makeTranslation(self.b_2_1_en, 'ca')
        transaction.commit()
        self.b_2_1_ca.edit(id='b_2_1_ca', language='ca')

        relocator_view = getMultiAdapter((self.portal, self.request),
                                          name='relocate-content')
        relocator_view.step1andstep2()

        self.assertTrue(getattr(self.portal, 'b_1_1_en', False))
        self.assertTrue(getattr(self.portal, 'a_1_1_ca', False))
        self.assertEqual(self.a_en.objectIds(), ['a_1_2_en', 'a_2_1_en'])
        self.assertEqual(self.a_en.b_1_1_en.objectIds(), ['b_2_1_en'])
        self.assertEqual(self.b_ca.objectIds(), ['b_2_1_ca'])
        self.assertEqual(self.b_ca.a_1_1_ca.objectIds(), ['a_2_2_ca'])

        workflowTool = getToolByName(self.portal, "portal_workflow")
        workflowTool.setDefaultChain('simple_publication_workflow')
        setupTool = SetupMultilingualSite()
        setupTool.setupSite(self.portal)

        relocator_view.step3()

        # Test that the resultant Plone site is 'clean'
        rlfs = [rlf for rlf in self.portal.objectIds() if ITranslatable.providedBy(getattr(self.portal, rlf))]
        self.assertEqual(rlfs, ['en', 'ca', 'shared'])
コード例 #46
0
def defaultLanguage(self):
    """Returns the initial default language."""
    parent = aq_parent(aq_inner(self))
    if ITranslatable.providedBy(parent):
        language = parent.Language()
        if language:
            return parent.Language()

    oshaiew = self.restrictedTraverse('@@oshaview')
    site_url = oshaiew.subsiteRootPath()
    site = self.restrictedTraverse(site_url)
    language_tool = getToolByName(site, 'portal_languages', None)
    if language_tool:
        if language_tool.startNeutral():
            return ''
        else:
            return language_tool.getPreferredLanguage()
    else:
        return LANGUAGE_DEFAULT
コード例 #47
0
ファイル: syncer.py プロジェクト: witsch/Products.LinguaPlone
    def _sync_withids(self, collection, criterion, value, source_value):
        source_coll = aq_parent(self.context)
        # Filter out simple dots as in '.././foo' and normalize backslashes
        norm_value = source_value.replace('\\', '/').split('/')
        norm_value = '/'.join([n for n in norm_value if n != '.'])
        try:
            source_obj = source_coll.unrestrictedTraverse(norm_value)
        except (AttributeError, KeyError):
            # The source object couldn't be found, keep the value
            criterion.setRelativePath(source_value)
            return

        language = collection.Language()
        obj = None
        if ITranslatable.providedBy(source_obj):
            obj = source_obj.getTranslation(language)
        if obj is not None:
            obj_path = obj.getPhysicalPath()
            source_path = source_obj.getPhysicalPath()
            target_value = source_value.split('/')
            # What follows assumes that the distance between the source
            # collection and source object is the same as the one in the
            # translated language
            ppath = zip(source_path, obj_path)
            len_ppath = len(ppath)
            for pos, (s, t) in enumerate(ppath):
                reverse_pos = pos - len_ppath
                if s == t:
                    # skip the common root elements
                    continue
                elif target_value[reverse_pos] == s:
                    # replace the id with the translated id
                    target_value[reverse_pos] = t
                else:
                    # Mismatching ids covered by a '..'
                    pass
            target_value = '/'.join(target_value)
            criterion.setRelativePath(target_value)
            return

        # If we cannot figure things out, we set the source
        criterion.setRelativePath(source_value)
コード例 #48
0
ファイル: utils.py プロジェクト: mvaled/Products.LinguaPlone
def translated_references(context, language, sources):
    """Convert the given sources into a list of targets in the given language,
    should those exist."""
    if not sources:
        return sources
    if not isinstance(sources, (list, tuple)):
        sources = [sources]

    result = []
    catalog = getToolByName(context, 'uid_catalog')
    for source in sources:
        if not source:
            continue
        if isinstance(source, basestring):
            # if we get a uid, lookup the object
            brains = catalog(UID=source)
            new = None
            for brain in brains:
                # gracefully deal with multiple objects per uid
                try:
                    new = brain.getObject()
                except AttributeError:  # pragma: no cover
                    pass
                if new is not None:
                    source = new
                    break

        target = source
        if ITranslatable.providedBy(source):
            canonical = source.getCanonical()
            brains = canonical.getTranslationBackReferences()
            found = [b for b in brains if b.Language == language]
            if found:
                target = found[0].sourceUID
            else:
                target = canonical.UID()
        result.append(target)
    return result
コード例 #49
0
    def __call__(self):
        event = self.event
        service_to_ping = self.element.service_to_ping
        obj = self.event.object
        container = obj.getParentNode()
        noasync_msg = 'No instance for async operations was defined.'

        def pingCRSDS(service_to_ping, obj_url, create):
            """ Ping the CR/SDS service
            """
            if async_service is None:
                logger.warn("Can't pingCRSDS, plone.app.async not installed!")
                return

            options = {}
            options['service_to_ping'] = service_to_ping
            options['obj_url'] = self.sanitize_url(obj_url)
            options['create'] = create
            queue = async_service.getQueues()['']
            try:
                async_service.queueJobInQueue(queue, ('rdf', ), ping_CRSDS,
                                              self.context, options)
            except ComponentLookupError:
                logger.info(noasync_msg)

        def pingCRSDS_backrel(service_to_ping, obj, create):
            """ Ping backward relations
            """
            back_relations = obj.getBRefs('relatesTo')
            for rel in back_relations:
                if rel is not None:
                    obj_url = "%s/@@rdf" % rel.absolute_url()
                    pingCRSDS(service_to_ping, obj_url, create)

        def pingCRSDS_children(service_to_ping, obj, create):
            """ Ping all sub-objects
            """
            if obj.portal_type == "Discussion Item":
                # 22047 skip object if it's of type Discussion Item
                return
            for child in obj.objectIds():
                child_obj = obj.get(child)
                if not child_obj:
                    logger.info("Couldn't retrieve child id %s for %s", child,
                                obj.absolute_url())
                    continue
                obj_url = "%s/@@rdf" % child_obj.absolute_url()
                pingCRSDS(service_to_ping, obj_url, create)
                pingCRSDS_children(service_to_ping, child_obj, create)

        # When no request the task is called from a async task, see #19830
        request = getattr(obj, 'REQUEST', None)

        # Detect special object used to force acquisition, see #18904
        if isinstance(request, str):
            request = None

        create = IObjectAddedEvent.providedBy(event)

        if service_to_ping == "":
            return

        if hasVersionsInstalled and IVersionEnhanced.providedBy(obj) \
                and request:
            obj_versions = IGetVersions(obj).versions()
        else:
            obj_versions = [obj]

        async_service = queryUtility(IAsyncService)

        # If object has translations
        if hasLinguaPloneInstalled and ITranslatable.providedBy(obj):
            if obj.isCanonical():
                # Ping all translations
                for trans in obj.getTranslations().items():
                    if trans[0] != 'en':
                        trans_obj = trans[1][0]
                        obj_url = trans_obj.absolute_url()
                        pingCRSDS(service_to_ping, obj_url, create)
            else:
                # Ping only canonical
                can_obj = obj.getCanonical()
                obj_url = can_obj.absolute_url()
                pingCRSDS(service_to_ping, obj_url, create)

        # If object was deleted
        if IObjectRemovedEvent.providedBy(event):
            # Ping backward relations
            pingCRSDS_backrel(service_to_ping, obj, create)

            # Ping all sub-objects
            pingCRSDS_children(service_to_ping, obj, create)

        # If object was moved/renamed first ping with the old object's URL
        if IObjectMovedOrRenamedEvent.providedBy(event):
            obj_url = "%s/%s/@@rdf" % (event.oldParent.absolute_url(),
                                       event.oldName)
            pingCRSDS(service_to_ping, obj_url, False)

            # then ping with the container of the old object
            obj_url = "%s/@@rdf" % event.oldParent.absolute_url()
            pingCRSDS(service_to_ping, obj_url, False)

            # Ping backward relations
            pingCRSDS_backrel(service_to_ping, obj, create)

            # Ping all sub-objects
            pingCRSDS_children(service_to_ping, obj, create)

        # Ping each version
        for obj in obj_versions:
            obj_url = "%s/@@rdf" % obj.absolute_url()
            pingCRSDS(service_to_ping, obj_url, create)

        # If no Aquisition there is no container, see #18904
        if container:
            obj_url = "%s/@@rdf" % container.absolute_url()
            pingCRSDS(service_to_ping, obj_url, False)

        return True
コード例 #50
0
    def getBreadcrumbs(self, path=None):
        """Get breadcrumbs"""
        result = []

        portal_state = self.context.restrictedTraverse('@@plone_portal_state')
        root = getNavigationRootObject(self.context, portal_state.portal())
        root_url = root.absolute_url()

        if path is not None:
            path = path.replace(root_url, '', 1).strip('/')
            root = aq_inner(root.restrictedTraverse(path))

        relative = aq_inner(
            self.context).getPhysicalPath()[len(root.getPhysicalPath()):]
        if path is None:
            # Add siteroot
            if IPloneSiteRoot.providedBy(root):
                icon = self.root_icon
            else:
                icon = self.folder_icon
            result.append({
                'title':
                translate(MessageFactory('plone')('Home'),
                          context=self.context.REQUEST),
                'url':
                root_url,
                'icon':
                '<img src="%s" width="16" height="16" />' % icon,
            })

        for i in range(len(relative)):
            now = relative[:i + 1]
            obj = aq_inner(root.restrictedTraverse(now))

            if IFolderish.providedBy(obj):
                if not now[-1] == 'talkback':
                    result.append({
                        'title':
                        obj.title_or_id(),
                        'url':
                        root_url + '/' + '/'.join(now),
                        'icon':
                        '<img src="%s" width="16" height="16" />' %
                        self.folder_icon,
                    })
        plone_root = IPloneSiteRoot(self.context, portal_state.portal())
        plone_root_url = plone_root.absolute_url()
        root_relative = aq_inner(
            self.context).getPhysicalPath()[len(plone_root.getPhysicalPath()):]
        for i in range(len(root_relative)):
            now = root_relative[:i + 1]
            obj = aq_inner(plone_root.restrictedTraverse(now))
            getUrlForLanguageCode = ''
            getTitleForLanguageCode = ''

            if IFolderish.providedBy(obj):
                if ITranslatable.providedBy(obj):
                    allTranslations = obj.getTranslations().keys()
                    currentLanguage = obj.Language()
                    if (currentLanguage
                            == 'de') and (obj.hasTranslation('en')):
                        getUrlForLanguageCode = obj.getTranslation(
                            'en').absolute_url()
                    if (currentLanguage
                            == 'en') and (obj.hasTranslation('de')):
                        getUrlForLanguageCode = obj.getTranslation(
                            'de').absolute_url()

                if not now[-1] == 'talkback':
                    result.append({
                        'getUrlForLanguageCode':
                        getUrlForLanguageCode,
                        'getTitleForLanguageCode':
                        translate(MessageFactory('linguaplone')(
                            "legend_existing_translations",
                            default="Existing translations"),
                                  context=self.context.REQUEST),
                        'currentLanguage':
                        currentLanguage,
                        'getParentFolderURL':
                        self.context.aq_inner.getParentNode().absolute_url(),
                        'getParentFolderTitle':
                        translate(MessageFactory('plone')(
                            'go_to_parent_url', default="Up one level"),
                                  context=self.context.REQUEST),
                    })

        return result
コード例 #51
0
ファイル: views.py プロジェクト: zmijunkie/silvuple
    def getContentByCanonical(self):
        """
        Gets a list of entries where content is arranged by its canonical language version.

        Each entry is a dictionary like:

            [
                ...
                [
                    { language : "en", available : true, title : "Foobar", canonical : True, url : "http://" },
                    { language : "fi", available : true, title : "Barbar", canonical : False, ... },
                    { language : "ru", available : false }
                ]
            ]

        Not available languages won't get any entries.
        """
        settings = self.getSettings()
        context = aq_inner(self.context)
        tools = getMultiAdapter((context, self.request), name="plone_tools")

        portal_catalog = tools.catalog()

        all_content = []

        if ITranslatable.providedBy(context):
            for lang, item in context.getTranslations(
                    review_state=False).items():
                all_content += portal_catalog(
                    Language="all",
                    path='/'.join(item.getPhysicalPath()),
                    portal_type=settings.contentTypes)
        else:
            all_content = portal_catalog(Language="all",
                                         path='/'.join(
                                             context.getPhysicalPath()),
                                         portal_type=settings.contentTypes)

        # List of UUID -> entry data mappings
        result = OrderedDict()

        # Create a dictionary entry populated with default languages,
        # so that languages come always in the same order
        # E.g. {en:{"available":False}}

        langs = self.getLanguages()

        def get_base_entry():
            """ Item row for all languages, everything set off by default """
            base_entry = OrderedDict()
            for lang in langs:
                base_entry[lang] = dict(available=False,
                                        language=lang,
                                        canTranslate=False)
            return base_entry

        def get_or_create_handle(translatable):
            """
            Get or create entry in the result listing.

            This is a dict of language -> data pairs
            """
            canonical = translatable.getCanonical()
            uuid = IUUID(canonical, None)

            if not uuid:
                raise RuntimeError("Object missing UUID: %s" % context)

            # Get the existing canonical entry
            # for the listing, or create a new empty
            # populated entry otherwise
            if uuid in result:
                return result[uuid]
            else:
                entry = get_base_entry()
                result[uuid] = entry
                return entry

        def can_translate(context, language):
            """ Check if required parent translations are in place so that we can translate this item

            :return: True if the item can be translated

            """

            assert context is not None

            parent = aq_parent(context)

            if ISiteRoot.providedBy(parent):
                return True

            # Parent is a language base folder at plone site root
            if INavigationRoot.providedBy(parent):
                return True

            if ITranslatable.providedBy(parent):
                translatable = ITranslatable(parent)
            else:
                from logging import getLogger
                log = getLogger('silvuple.views.can_translate')
                if parent:
                    log.info('Parent is not translatable: %s' %
                             parent.absolute_url())
                else:
                    log.error(
                        'Cannot translate language: %s, no parent for %s' %
                        (language, context.absolute_url()))

                return False

            translation = translatable.getTranslation(language)

            return translation is not None

        for brain in all_content:

            if not self.shouldTranslate(brain):
                continue

            try:
                context = brain.getObject()
            except Exception as e:
                logger.error("Could not load brain %s" % brain.getURL())
                logger.exception(e)
                continue

            if ITranslatable.providedBy(context):
                translatable = ITranslatable(context)
            else:
                from logging import getLogger
                log = getLogger('silvuple.views.can_translate')
                log.info('Content is not translatable: %s' %
                         context.absolute_url())
                continue

            try:
                entry = get_or_create_handle(translatable)
            except RuntimeError:
                from logging import getLogger
                log = getLogger('silvuple.views.getContentByCanonical')
                log.info('Item has no UUID: %s' & translatable.absolute_url())
                continue

            # Data exported to JSON + context object needed for post-processing
            data = dict(canonical=translatable.isCanonical(),
                        title=context.title_or_id(),
                        url=context.absolute_url(),
                        lang=map_language_id(context.Language()),
                        available=True,
                        path=context.absolute_url_path(),
                        context=context)

            entry[map_language_id(context.Language())] = data

        # Fill in items which can be translated
        for entry in result.values():

            canonical = None

            # First snatch canonical  item for this content
            for lang in entry.values():

                if lang.get("canonical", False):
                    canonical = lang["context"]

                # Do not leak out to JSON serialization
                lang["context"] = None

            if not canonical:
                logger.warn("No canonical content for %s" % entry)
                continue

            # Then populate untranslated languages
            for lang in entry.values():
                if not lang["available"]:

                    lang_code = lang["language"]

                    lang["canTranslate"] = can_translate(canonical, lang_code)

                    if canonical:
                        # Point to LinguaPlone Translate into... form
                        lang["url"] = "%s/@@translate?newlanguage=%s" % (
                            canonical.absolute_url(), lang_code)
                    else:
                        lang["url"] = "#"

        # Convert pre content entries to lists, so that we can guarantee
        # the order of langauges when passing thru JSON
        result = [entry.values() for entry in result.values()]

        self.sortContentListing(result)

        return result
コード例 #52
0
    def testMultiValuedReferenceFields(self):
        english = makeContent(self.folder, 'SimpleType', 'doc')
        english.setLanguage('en')
        german = makeTranslation(english, 'de')

        target = makeContent(self.folder, 'SimpleType', 'target')
        target.setLanguage('en')
        target_german = makeTranslation(target, 'de')

        target2 = makeContent(self.folder, 'SimpleType', 'target2')
        target2.setLanguage('en')
        target2_german = makeTranslation(target2, 'de')

        # untranslated target
        target3 = makeContent(self.folder, 'SimpleType', 'target3')
        target3.setLanguage('en')

        # targets with different language than sources
        target4 = makeContent(self.folder, 'SimpleType', 'target4')
        target4.setLanguage('fr')
        target4_italian = makeTranslation(target4, 'it')

        # untranslatable target (non-LP aware)
        target5 = makeContent(self.folder, 'UntranslatableType', 'target5')
        self.assertEqual(ITranslatable.providedBy(target5), False)

        # Test single valued
        english.setReferenceMulti(target.UID())
        self.assertEqual(english.getReferenceMulti()[0].UID(), target.UID())
        self.assertEqual(german.getReferenceMulti()[0].UID(),
            target_german.UID())

        # Test multi-valued
        english.setReferenceMulti([target.UID(), target2.UID()])
        self.assertEqual(set(english.getReferenceMulti()),
            set([target, target2]))
        self.assertEqual(set(german.getReferenceMulti()),
            set([target_german, target2_german]))

        # Test multi-valued from tuple
        english.setReferenceMulti((target.UID(), target2.UID()))
        self.assertEqual(set(english.getReferenceMulti()),
            set([target, target2]))
        self.assertEqual(set(german.getReferenceMulti()),
            set([target_german, target2_german]))

        # test reduce references
        english.setReferenceMulti([target.UID()])
        self.assertEqual(len(english.getReferenceMulti()), 1)

        # test delete references
        english.setReferenceMulti([])
        self.assertEqual(len(english.getReferenceMulti()), 0)

        # test with untranslated target, german points to only canonical target
        english.setReferenceMulti([target3.UID()])
        self.assertEqual(english.getReferenceMulti()[0].UID(), target3.UID())
        self.assertEqual(german.getReferenceMulti()[0].UID(), target3.UID())

        # test with an untranslatable target
        english.setReferenceMulti([target5.UID()])
        self.assertEqual(english.getReferenceMulti()[0].UID(), target5.UID())
        self.assertEqual(german.getReferenceMulti()[0].UID(), target5.UID())

        # test with untranslatable and translatable mixed targets
        english.setReferenceMulti([target.UID(), target5.UID()])
        self.assertEqual(set(english.getReferenceMulti()),
            set([target, target5]))
        self.assertEqual(set(german.getReferenceMulti()),
            set([target_german, target5]))

        # test remove translatable from the list
        english.setReferenceMulti([target5.UID()])
        self.assertEqual(english.getReferenceMulti()[0].UID(), target5.UID())
        self.assertEqual(german.getReferenceMulti()[0].UID(), target5.UID())

        # test with different language on targets, "fr" is canonical
        english.setReferenceMulti([target4.UID()])
        self.assertEqual(english.getReferenceMulti()[0].UID(), target4.UID())
        self.assertEqual(german.getReferenceMulti()[0].UID(), target4.UID())

        # after adding an italian content, it must point to italian target
        italian = makeTranslation(english, 'it')
        self.assertEqual(italian.getReferenceMulti()[0].UID(),
                         target4_italian.UID())

        # test edge cases, can we use None to delete references?
        english.setReferenceMulti(None)

        # can we delete things via an empty string?
        english.setReferenceMulti([target2])
        english.setReferenceMulti('')
        self.failUnless(len(english.getReferenceMulti()) == 0)

        english.setReferenceMulti([target2])
        english.setReferenceMulti([''])
        self.failUnless(len(english.getReferenceMulti()) == 0)

        # can we use a content object instead of its UID?
        english.setReferenceMulti([target2])
        self.assertEqual(english.getReferenceMulti()[0].UID(), target2.UID())
        self.assertEqual(
            german.getReferenceMulti()[0].UID(), target2_german.UID())
コード例 #53
0
 def mutator(value, **kw):
     if (not ITranslatable.providedBy(instance)
             or not self.languageIndependent):
         return self.getTranslationMutator(instance)(value, **kw)
     # Use the generatedMutator from LinguaPlone
     return generatedMutator(instance, value, **kw)
コード例 #54
0
def isTranslatable(content):
    """Detects translatable objects when LP installed"""
    # FIXME: Should we check that LP is installed in this site too ?
    if HAS_LINGUAPLONE:
        return ITranslatable.providedBy(content)