示例#1
0
    def __call__(self, **kwargs):
        settings = self.parseRegistry()
        config = {}
        config = self.mapFormatCategories(settings, config)
        config = self.mapFormats(settings, config)
        config = self.mapActions(settings, config)
        config = self.mapTilesCategories(settings, config)
        for tile_category in ['structure_tiles', 'app_tiles']:
            config = self.mapTiles(settings, config, tile_category)
        config = self.mapFieldTiles(settings, config, kwargs)

        args = {
            'type': None,
            'context': None,
            'request': None,
        }
        args.update(kwargs)
        if IFolderish.providedBy(args['context']):
            config['parent'] = args['context'].absolute_url() + "/"
        elif args['context']:
            config['parent'] = getattr(args['context'].aq_inner, 'aq_parent',
                                       None).absolute_url() + "/"
        else:
            # context can be None, at least in tests.  Do nothing
            # then.  See test_config in test_mosaicregistry.py
            pass

        return config
示例#2
0
    def __call__(self, **kwargs):
        settings = self.parseRegistry()
        config = {}
        config = self.mapFormatCategories(settings, config)
        config = self.mapFormats(settings, config)
        config = self.mapTinyMCEActionCategories(settings, config)
        config = self.mapTinyMCEToolbarFormats(settings, config)
        config = self.mapTinyMCEContextMenuFormats(settings, config)
        config = self.mapActions(settings, config)
        config = self.mapTilesCategories(settings, config)
        for tile_category in ["structure_tiles", "app_tiles"]:
            config = self.mapTiles(settings, config, tile_category)
        config = self.mapFieldTiles(settings, config, kwargs)

        args = {"type": None, "context": None, "request": None}
        args.update(kwargs)
        if IFolderish.providedBy(args["context"]):
            config["parent"] = args["context"].absolute_url() + "/"
        elif args["context"]:
            config["parent"] = getattr(args["context"].aq_inner, "aq_parent", None).absolute_url() + "/"
        else:
            # context can be None, at least in tests.  Do nothing
            # then.  See test_config in test_mosaicregistry.py
            pass

        return config
    def getBreadcrumbs(self, path=None):
        """Get breadcrumbs"""
        result = []

        root_url = getNavigationRoot(self.context)
        root = aq_inner(self.context.restrictedTraverse(root_url))
        root_url = root.absolute_url()

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

        relative = aq_inner(self.context).getPhysicalPath()[len(root.getPhysicalPath()):]
        if path is None:
            # Add siteroot
            result.append({'title': root.title_or_id(), 'url': '/'.join(root.getPhysicalPath())})

        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)})
        return result
示例#4
0
    def tinymce(self):
        """
        data-pat-tinymce : JSON.stringify({
            relatedItems: {
              vocabularyUrl: config.portal_url +
                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
            },
            tiny: config,
            prependToUrl: 'resolveuid/',
            linkAttribute: 'UID',
            prependToScalePart: '/@@images/image/'
          })
        """

        generator = TinyMCESettingsGenerator(self.context, self.request)
        settings = generator.settings

        folder = aq_inner(self.context)
        # Test if we are currently creating an Archetype object
        if IFactoryTempFolder.providedBy(aq_parent(folder)):
            folder = aq_parent(aq_parent(aq_parent(folder)))
        if not IFolderish.providedBy(folder):
            folder = aq_parent(folder)

        if IPloneSiteRoot.providedBy(folder):
            initial = None
        else:
            initial = IUUID(folder, None)
        current_path = folder.absolute_url()[len(generator.portal_url):]

        image_types = settings.image_objects or []
        folder_types = settings.contains_objects or []
        configuration = {
            'relatedItems': {
                'vocabularyUrl':
                    '%s/@@getVocabulary?name=plone.app.vocabularies.Catalog' % (
                        generator.portal_url),
                'folderTypes': folder_types
            },
            'upload': {
                'initialFolder': initial,
                'currentPath': current_path,
                'baseUrl': generator.portal_url,
                'relativePath': '@@fileUpload',
                'uploadMultiple': False,
                'maxFiles': 1,
                'showTitle': False
            },
            'base_url': self.context.absolute_url(),
            'tiny': generator.get_tiny_config(),
            # This is for loading the languages on tinymce
            'loadingBaseUrl': '%s/++plone++static/components/tinymce-builded/js/tinymce' % generator.portal_url,  # noqa
            'prependToUrl': '{0}/resolveuid/'.format(generator.portal_url),
            'linkAttribute': 'UID',
            'prependToScalePart': '/@@images/image/',
            'imageTypes': image_types
            # 'anchorSelector': utility.anchor_selector,
        }

        return {'data-pat-tinymce': json.dumps(configuration)}
示例#5
0
    def __call__(self):
        """
        data-pat-tinymce : JSON.stringify({
            relatedItems: {
              vocabularyUrl: config.portal_url + '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
            },
            rel_upload_path: '@@fileUpload',
            folder_url: config.document_base_url,
            tiny: config,
            prependToUrl: 'resolveuid/',
            linkAttribute: 'UID',
            prependToScalePart: '/@@images/image/'
          })
        """

        folder = self.context
        if not IFolderish.providedBy(self.context):
            folder = aq_parent(self.context)
        if IPloneSiteRoot.providedBy(folder):
            initial = None
        else:
            initial = IUUID(folder, None)
        current_path = folder.absolute_url()[len(self.config['portal_url']):]
        configuration = {
            'relatedItems': format_pattern_settings(
                self.settings.relatedItems,
                self.config),
            'upload': {
                'initialFolder': initial,
                'currentPath': current_path,
                'baseUrl': self.config['document_base_url'],
                'relativePath': format_pattern_settings(
                    self.settings.rel_upload_path,
                    self.config),
                'uploadMultiple': False,
                'maxFiles': 1,
                'showTitle': False
            },
            'base_url': self.config['document_base_url'],
            'tiny': {
                'content_css': self.settings.content_css,
            },
            # This is for loading the languages on tinymce
            'loadingBaseUrl': '++plone++static/components/tinymce-builded/js/tinymce',
            'prependToUrl': 'resolveuid/',
            'linkAttribute': format_pattern_settings(
                self.settings.linkAttribute,
                self.config),
            'prependToScalePart': format_pattern_settings(
                self.settings.prependToScalePart,
                self.config),
            # XXX need to get this from somewhere...
            'folderTypes': ','.join(['Folder']),
            'imageTypes': ','.join(['Image']),
            #'anchorSelector': utility.anchor_selector,
            #'linkableTypes': utility.linkable.replace('\n', ',')
        }

        return {'data-pat-tinymce': json.dumps(configuration)}
    def getListing(self, filter_portal_types, rooted, document_base_url, upload_type=None):
        """Returns the actual listing"""

        catalog_results = []
        results = {}

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = object.getParentNode()

        if INavigationRoot.providedBy(object) or (rooted == "True" and document_base_url[:-1] == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = object.getParentNode().absolute_url()

        if rooted == "True":
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        for brain in portal_catalog(portal_type=filter_portal_types, sort_on='getObjPositionInParent', path={'query': path, 'depth': 1}):
            if brain.is_folderish:
                icon = self.folder_icon
            else:
                icon = self.picture_icon

            catalog_results.append({
                'id': brain.getId,
                'uid': brain.UID or None,  # Maybe Missing.Value
                'url': brain.getURL(),
                'portal_type': brain.portal_type,
                'normalized_type': normalizer.normalize(brain.portal_type),
                'title': brain.Title == "" and brain.id or brain.Title,
                'icon': icon,
                'description': brain.Description,
                'is_folderish': brain.is_folderish,
                })

        # add catalog_ressults
        results['items'] = catalog_results

        # decide whether to show the upload new button
        results['upload_allowed'] = False
        if upload_type:
            portal_types = getToolByName(object, 'portal_types')
            fti = getattr(portal_types, upload_type, None)
            if fti is not None:
                results['upload_allowed'] = fti.isConstructionAllowed(object)

        # return results in JSON format
        self.context.REQUEST.response.setHeader("Content-type", "application/json")
        return json.dumps(results)
示例#7
0
def get_tinymce_options(context, field, request):
    args = {'pattern_options': {}}
    folder = context
    if not IFolderish.providedBy(context):
        folder = aq_parent(context)
    if IPloneSiteRoot.providedBy(folder):
        initial = None
    else:
        initial = IUUID(folder, None)
    portal_url = get_portal_url(context)
    current_path = folder.absolute_url()[len(portal_url):]

    utility = getToolByName(aq_inner(context), 'portal_tinymce', None)
    if utility:
        # Plone 4.3
        config = utility.getConfiguration(context=context,
                                          field=field,
                                          request=request)

        config['content_css'] = config['portal_url'] + '/base.css'
        del config['customplugins']
        del config['plugins']
        del config['theme']

        config['content_css'] = '++resource++plone.app.widgets-tinymce-content.css'
        args['pattern_options'] = {
            'relatedItems': {
                'vocabularyUrl': config['portal_url'] +
                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
            },
            'upload': {
                'initialFolder': initial,
                'currentPath': current_path,
                'baseUrl': config['document_base_url'],
                'relativePath': '@@fileUpload',
                'uploadMultiple': False,
                'maxFiles': 1,
                'showTitle': False
            },
            'tiny': config,
            # This is for loading the languages on tinymce
            'loadingBaseUrl': '++plone++static/components/tinymce-builded/js/tinymce',
            'prependToUrl': 'resolveuid/',
            'linkAttribute': 'UID',
            'prependToScalePart': '/@@images/image',
            'folderTypes': utility.containsobjects.replace('\n', ','),
            'imageTypes': utility.imageobjects.replace('\n', ','),
            'anchorSelector': utility.anchor_selector,
            'linkableTypes': utility.linkable.replace('\n', ',')
        }
    else:
        # Plone 5
        # They are setted on the body
        pattern_options = getMultiAdapter(
            (context, request, field),
            name="tinymce_settings")()['data-pat-tinymce']
        args['pattern_options'] = json.loads(pattern_options)
    return args
    def update(self):
        portal_state = getView(self.context, self.request, "plone_portal_state")
        self.portal_url = portal_state.portal_url()

        # Create <base href=""> directive of <head>
        if IFolderish.providedBy(self.context):
            # Folderish URLs must end to slash
            self.base = self.context.absolute_url() + "/"
        else:
            self.base = self.context.absolute_url()
示例#9
0
    def remove(self):
        super(AjaxFavoriteActions, self).remove()

        if IFolderish.providedBy(self.context):
            msg = _("The folder has been removed from your favorites")
        else:
            msg = _("The document has been removed from your favorites")

        return {'status': 'favorite-off',
                'msg': translate(msg, context=self.request)}
    def __init__(self, context, request, **kwargs):
        """ Contructor """
        self.context = context
        self.request = request
        util = api.content.get_view(u'plone', self.context, self.request)
        self.getIcon = util.getIcon

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(self.context):
            self.obj = aq_parent(self.context)
        else:
            self.obj = aq_inner(self.context)
示例#11
0
    def add(self):
        request = self.request
        view = request.get('view', '')
        super(FavoriteActions, self).add()

        statusmsg = IStatusMessage(request)
        if IFolderish.providedBy(self.context):
            statusmsg.add(_("The folder has been added to your favorites"))
        else:
            statusmsg.add(_("The document has been added to your favorites"))

        request.response.redirect(self.context.absolute_url() + '/' + view)
示例#12
0
    def get_navigation(self):
        directory = self.request.get('dir', './')
        base_query = json.loads(self.request.get('query', '{}'),
                           object_hook=_decode_dict)
        pprops = getToolByName(self.context, 'portal_properties')
        site_props = pprops.site_properties
        folder_types = site_props.getProperty(
            'typesLinkToFolderContentsInFC', ['Folder', 'Large Plone Folder'])
        query = base_query.copy()
        if 'portal_type' in query:
            if type(query['portal_type']) in (list, tuple, set):
                query['portal_type'] = list(query['portal_type'])
                query['portal_type'].extend(list(folder_types))
            else:
                pt = query['portal_type']
                query['portal_type'] = list(folder_types)
                query['portal_type'].append(pt)

        site = getSite()
        context = aq_inner(self.context)
        if directory == './':
            if IFolderish.providedBy(context):
                context = aq_parent(context)
        elif directory == '/':
            context = site
        else:
            context = site.restrictedTraverse(directory)

        results = context.getFolderContents(contentFilter=base_query)
        html = '<ul class="jqueryFileTree" style="display: none;">'
        site_path = '/'.join(site.getPhysicalPath())
        for item in context.getFolderContents(contentFilter=query):
            path = item.getPath()[len(site_path) + 1:]
            klass = ''
            if aq_base(item) not in results:
                klass = 'unselectable'
            if item.portal_type in folder_types:
                html += """<li class="directory collapsed %s">
    <a class="item" href="#" rel="%s">%s</a></li>""" % (
                    klass,
                    path + '/',
                    item.Title
                )
            else:
                html += """<li class="file ext_txt %s">
    <a class="item" href="#" rel="%s">%s</a></li>""" % (
                    klass,
                    path,
                    item.Title
                )
        html += '</ul>'
        return html
示例#13
0
    def remove(self):
        super(FavoriteActions, self).remove()

        statusmsg = IStatusMessage(self.request)
        if IFolderish.providedBy(self.context):
            statusmsg.add(_("The folder has been removed from your favorites"))
        else:
            statusmsg.add(_("The document has been removed from your favorites"))

        site_properties = getToolByName(self.context, 'portal_properties').site_properties
        useView = self.context.portal_type in site_properties.typesUseViewActionInListings
        url = self.context.absolute_url() + (useView and "/view" or "")
        self.request.response.redirect(url)
示例#14
0
 def __init__(self, context, query=None, include_subfolders=False):
     if not IFolderish.providedBy(context):
         raise ValueError('context does not appear to be a folder')
     self.context = context
     if query and not IComposedQuery.providedBy(query):
         raise ValueError('query does not provide IComposedQuery')
     elif query is None:
         query = ComposedQuery()
     self.query = query
     sm = sitemanager_for(self.context)
     self.cachetools = sm.queryUtility(ISetCacheTools)
     if self.cachetools is None:
         raise ComponentLookupError('cannot find local set cache utility')
     self.include_subfolders = include_subfolders
示例#15
0
    def __init__(self, context, request, **kwargs):
        """ Contructor """
        self.context = context
        self.request = request
        self.catalog = getToolByName(self.context, "portal_catalog")
        self.plone_view = getMultiAdapter((self.context, self.request), name=u"plone")
        self.getIcon = self.plone_view.getIcon
        self.registry = getUtility(IRegistry)
        self.settings = self.registry.forInterface(ICoverSettings)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(self.context):
            self.obj = aq_parent(self.context)
        else:
            self.obj = aq_inner(self.context)
    def recurse(context):
        """ Recurse through all content on Plone site """

        annotations = IAnnotations(context)

        if name in annotations:
            msg = "Cleaning up annotation %s on item %s"
            msg = msg % (name, context.absolute_url())
            logger.info(msg)
            del annotations[name]

        # Make sure that we recurse to real folders only,
        # otherwise contentItems() might be acquired from higher level
        if IFolderish.providedBy(context):
            for id, item in context.contentItems():
                recurse(item)
    def getListing(self, filter_portal_types, rooted, document_base_url, upload_type=None, interface=''):
        """Returns the actual listing"""

        iface = interface.__identifier__ if interface else ''
        catalog_results = []
        results = {}

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        if INavigationRoot.providedBy(object) or (rooted == 'True' and document_base_url[:-1] == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = aq_parent(object).absolute_url()

        if rooted == 'True':
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        for brain in portal_catalog(portal_type=filter_portal_types, sort_on='getObjPositionInParent', path={'query': path, 'depth': 1}, object_provides=iface):
            catalog_results.append({
                'id': brain.getId,
                'uid': brain.UID or None,  # Maybe Missing.Value
                'url': brain.getURL(),
                'portal_type': brain.portal_type,
                'normalized_type': normalizer.normalize(brain.portal_type),
                'title': brain.Title == '' and brain.id or brain.Title,
                'icon': brain.getIcon,
                'is_folderish': brain.is_folderish,
                'i_type': str(interface)
            })

        # add catalog_ressults
        results['items'] = catalog_results

        # return results in JSON format
        return json.dumps(results)
示例#18
0
    def remove(self):
        request = self.request
        user = request.AUTHENTICATED_USER
        view = request.get('view', '')
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        site = getNavigationRootObject(self.context, portal)
        IFavoriteStorage(site).remove_favorite(user.getId(),
                                                 id=IUUID(self.context))


        statusmsg = IStatusMessage(request)
        if IFolderish.providedBy(self.context):
            statusmsg.add(_("The folder has been removed from your favorites"))
        else:
            statusmsg.add(_("The document has been removed from your favorites"))

        request.response.redirect(self.context.absolute_url() + '/' + view)
示例#19
0
    def action(self, obj):
        transitions = self.pworkflow.getTransitionsFor(obj)
        if self.transition_id in [t["id"] for t in transitions]:
            try:
                # set effective date if not already set
                if obj.EffectiveDate() == "None":
                    obj.setEffectiveDate(DateTime())

                self.pworkflow.doActionFor(obj, self.transition_id, comment=self.comments)
                if self.putils.isDefaultPage(obj):
                    self.action(obj.aq_parent.aq_parent)
                if self.recurse and IFolderish.providedBy(obj):
                    for sub in obj.values():
                        self.action(sub)
            except ConflictError:
                raise
            except Exception:
                self.errors.append(_("Could not transition: ${title}", mapping={"title": self.objectTitle(obj)}))
    def render(self, search_for='', path='', media_type='video',
               folders=True):
        """ """
        results = []
        normalizer = getUtility(IIDNormalizer)
        object = aq_inner(self.context)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        path = '/'.join(object.getPhysicalPath())

        catalog = getToolByName(self.context, 'portal_catalog')
        medias = {'video': IVideo, 'audio': IAudio}
        iface = medias[media_type]
        media_results = catalog(object_provides=iface.__identifier__,
                                sort_on='created', Title=search_for,
                                path={'query': path, 'depth': 1})

        utility = getUtility(ITinyMCE)
        folder_portal_types = []
        if folders and not search_for:
            folder_portal_types.extend(utility.containsobjects.split('\n'))
            folders_results = catalog(portal_type=folder_portal_types,
                                      sort_on='getObjPositionInParent',
                                      path={'query': path, 'depth': 1})
            media_results = folders_results + media_results

        for brain in media_results:
            results.append({
                'id': brain.getId,
                'uid': brain.UID or None,  # Maybe Missing.Value
                'url': brain.getURL(),
                'portal_type': brain.portal_type,
                'normalized_type': normalizer.normalize(brain.portal_type),
                'title': brain.Title == '' and brain.id or brain.Title,
                'icon': brain.getIcon,
                'is_folderish': brain.is_folderish,
                'itype': 'folder' if brain.is_folderish else media_type
            })

        return json.dumps(results)
    def __call__(self, context):
        context = getattr(context, 'context', context)
        portal_url = getToolByName(context, 'portal_url')
        site = portal_url.getPortalObject()
        new_list = []
        pt = getToolByName(site, 'portal_types')
        types = pt.listTypeInfo()
        for site_type in types:
            if (site_type.global_allow is True) and \
               (site_type.isConstructionAllowed(site) == True):
                type_id = site_type.getId()
                site.invokeFactory(type_id, 'item')
                item = site['item']
                if IFolderish.providedBy(item):
                        new_list.append(SimpleTerm(type_id,
                                        type_id))

                del site['item']
        return SimpleVocabulary(new_list)
    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))

        phisycal_path = aq_inner(self.context).getPhysicalPath()
        relative = phisycal_path[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(PMF("Home"), context=self.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))
            icon_snippet = '<img src="%s" width="16" height="16" />'
            if IFolderish.providedBy(obj):
                if not now[-1] == "talkback":
                    result.append(
                        {
                            "title": obj.title_or_id(),
                            "url": root_url + "/" + "/".join(now),
                            "icon": icon_snippet % self.folder_icon,
                        }
                    )
        return result
 def __call__(self, context):
     context = getattr(context, 'context', context)
     portal_url = getToolByName(context, 'portal_url')
     site = portal_url.getPortalObject()
     pt = getToolByName(site, 'portal_types')
     # Use only Friendly Types
     util = queryUtility(IVocabularyFactory, 'plone.app.vocabularies.ReallyUserFriendlyTypes')
     types = util(context)
     types_ids = types.by_token.keys()
     folderish = []
     for type_id in types_ids:
         site_type = pt[type_id]
         if (site_type.global_allow) and (site_type.isConstructionAllowed(site)):
             term = types.by_token[type_id]
             site.invokeFactory(type_id, 'item')
             item = site['item']
             if IFolderish.providedBy(item):
                 folderish.append(term)
             del site['item']
     return SimpleVocabulary(folderish)
示例#24
0
    def action(self, obj, bypass_recurse=False):
        transitions = self.pworkflow.getTransitionsFor(obj)
        if self.transition_id in [t['id'] for t in transitions]:
            try:
                # set effective date if not already set
                if obj.EffectiveDate() == 'None':
                    obj.setEffectiveDate(DateTime())

                self.pworkflow.doActionFor(obj, self.transition_id,
                                           comment=self.comments)
                if self.putils.isDefaultPage(obj):
                    self.action(obj.aq_parent, bypass_recurse=True)
                recurse = self.recurse and not bypass_recurse
                if recurse and IFolderish.providedBy(obj):
                    for sub in obj.values():
                        self.action(sub)
            except ConflictError:
                raise
            except Exception:
                self.errors.append('Could not transition: %s' % (
                    self.objectTitle(obj)))
    def add(self):
        request = self.request
        view = request.get('view', '')
        portal = getToolByName(self.context, 'portal_url').getPortalObject()
        site = getNavigationRootObject(self.context, portal)
        ISuggestionsStorage(site).add_suggestion(
                id=IUUID(self.context),
                type='uid',
                view=view,
                date=datetime.now())

        if IFolderish.providedBy(self.context):
            IStatusMessage(self.request).addStatusMessage(
                        _("The folder has been added to suggestions"))
        elif IContentish.providedBy(self.context):
            IStatusMessage(self.request).addStatusMessage(
                        _("The document has been added to suggestions"))
        else:
            IStatusMessage(self.request).addStatusMessage(
                        _("The element has been added to suggestions"))

        self.request.response.redirect(self.context.absolute_url() + '/' + view)
    def getBreadcrumbs(self, path=None):
        """Get breadcrumbs"""
        result = []

        root_url = getNavigationRoot(self.context)
        root = aq_inner(self.context.restrictedTraverse(root_url))
        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': root.title_or_id(),
                'url': '/'.join(root.getPhysicalPath()),
                '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,
                    })
        return result
示例#27
0
    def tinymce(self):
        """
        data-pat-tinymce : JSON.stringify({
            relatedItems: {
              vocabularyUrl: config.portal_url +
                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
            },
            tiny: config,
            prependToUrl: 'resolveuid/',
            linkAttribute: 'UID',
            prependToScalePart: '/@@images/image/'
          })
        """

        generator = TinyMCESettingsGenerator(self.context, self.request)
        settings = generator.settings
        folder = aq_inner(self.context)

        # Test if we are currently creating an Archetype object
        if IFactoryTempFolder.providedBy(aq_parent(folder)):
            folder = aq_parent(aq_parent(aq_parent(folder)))
        if not IFolderish.providedBy(folder):
            folder = aq_parent(folder)

        if IPloneSiteRoot.providedBy(folder):
            initial = None
        else:
            initial = IUUID(folder, None)

        portal = get_portal()
        portal_url = portal.absolute_url()
        current_path = folder.absolute_url()[len(portal_url):]

        image_types = settings.image_objects or []

        server_url = self.request.get("SERVER_URL", "")
        site_path = portal_url[len(server_url):]

        related_items_config = get_relateditems_options(
            context=self.context,
            value=None,
            separator=";",
            vocabulary_name="plone.app.vocabularies.Catalog",
            vocabulary_view="@@getVocabulary",
            field_name=None,
        )
        related_items_config = call_callables(related_items_config,
                                              self.context)

        configuration = {
            "base_url":
            self.context.absolute_url(),
            "imageTypes":
            image_types,
            "imageScales":
            self.image_scales,
            "linkAttribute":
            "UID",
            # This is for loading the languages on tinymce
            "loadingBaseUrl":
            "{}/++plone++static/components/tinymce-builded/"
            "js/tinymce".format(portal_url),
            "relatedItems":
            related_items_config,
            "prependToScalePart":
            "/@@images/image/",
            "prependToUrl":
            "{}/resolveuid/".format(site_path.rstrip("/")),
            "tiny":
            generator.get_tiny_config(),
            "upload": {
                "baseUrl": portal_url,
                "currentPath": current_path,
                "initialFolder": initial,
                "maxFiles": 1,
                "relativePath": "@@fileUpload",
                "showTitle": False,
                "uploadMultiple": False,
            },
        }
        return {"data-pat-tinymce": json.dumps(configuration)}
    def getListing(self, filter_portal_types, rooted, document_base_url, upload_type=None, image_types=None):
        """Returns the actual listing"""
        catalog_results = []
        results = {}
        image_types = image_types or []

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        if INavigationRoot.providedBy(object) or (rooted == "True" and document_base_url[:-1] == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = aq_parent(object).absolute_url()

        if rooted == "True":
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        plone_layout = self.context.restrictedTraverse('@@plone_layout', None)
        if plone_layout is None:
            # Plone 3
            plone_view = self.context.restrictedTraverse('@@plone')
            getIcon = lambda brain: plone_view.getIcon(brain).html_tag()
        else:
            # Plone >= 4
            getIcon = lambda brain: plone_layout.getIcon(brain)()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        query = self.listing_base_query.copy()
        query.update({'portal_type': filter_portal_types,
                      'sort_on': 'getObjPositionInParent',
                      'path': {'query': path, 'depth': 1}})
        for brain in portal_catalog(**query):
            catalog_results.append({
                'id': brain.getId,
                'uid': brain.UID or None,  # Maybe Missing.Value
                'url': brain.getURL(),
                'portal_type': brain.portal_type,
                'normalized_type': normalizer.normalize(brain.portal_type),
                'title': brain.Title == "" and brain.id or brain.Title,
                'icon': getIcon(brain),
                'description': brain.Description,
                'is_folderish': brain.is_folderish,
                })

        # add catalog_ressults
        results['items'] = catalog_results

        # decide whether to show the upload new button
        results['upload_allowed'] = False
        if upload_type:
            portal_types = getToolByName(object, 'portal_types')
            fti = getattr(portal_types, upload_type, None)
            if fti is not None:
                results['upload_allowed'] = fti.isConstructionAllowed(object)

        # return results in JSON format
        self.context.REQUEST.response.setHeader("Content-type", "application/json")
        return json.dumps(results)
    def getListing(self,
                   filter_portal_types,
                   rooted,
                   document_base_url,
                   upload_type=None,
                   interface=''):
        """Returns the actual listing"""

        iface = interface.__identifier__ if interface else ''
        catalog_results = []
        results = {}

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        if INavigationRoot.providedBy(object) or (rooted == 'True'
                                                  and document_base_url[:-1]
                                                  == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = aq_parent(object).absolute_url()

        if rooted == 'True':
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        for brain in portal_catalog(portal_type=filter_portal_types,
                                    sort_on='getObjPositionInParent',
                                    path={
                                        'query': path,
                                        'depth': 1
                                    },
                                    object_provides=iface):
            catalog_results.append({
                'id':
                brain.getId,
                'uid':
                brain.UID or None,  # Maybe Missing.Value
                'url':
                brain.getURL(),
                'portal_type':
                brain.portal_type,
                'normalized_type':
                normalizer.normalize(brain.portal_type),
                'title':
                brain.Title == '' and brain.id or brain.Title,
                'icon':
                brain.getIcon,
                'is_folderish':
                brain.is_folderish,
                'i_type':
                str(interface)
            })

        # add catalog_ressults
        results['items'] = catalog_results

        # return results in JSON format
        return json.dumps(results)
示例#30
0
def on_content_state_changed(obj, event):
    obj.reindexObject(idxs=['has_private_parents'])
    if IFolderish.providedBy(obj):
        tasks.reindex_children.delay(obj, ['has_private_parents'])
示例#31
0
    def getConfiguration(self, context=None, field=None, request=None):
        """Return configuration as a dictionary

        :param field: Dexterity or Archetypes Field instance

        :param context: The TinyMCE editor content items

        :return: JSON string of the TinyMCE configuration for this field
        """
        results = {}

        # Get widget attributes
        widget = getattr(field, 'widget', None)
        filter_buttons = getattr(widget, 'filter_buttons', None)
        allow_buttons = getattr(widget, 'allow_buttons', None)
        redefine_parastyles = getattr(widget, 'redefine_parastyles', None)
        parastyles = getattr(widget, 'parastyles', None)
        rooted = getattr(widget, 'rooted', False)
        toolbar_width = getattr(widget, 'toolbar_width', self.toolbar_width)

        # Get safe html transform
        safe_html = getattr(getToolByName(self, 'portal_transforms'),
                            'safe_html')

        # Get kupu library tool filter
        # Settings are stored on safe_html transform in Plone 4 and
        # on kupu tool in Plone 3.
        kupu_library_tool = getToolByName(self, 'kupu_library_tool', None)

        # Remove to be stripped attributes
        try:
            style_whitelist = safe_html.get_parameter_value('style_whitelist')
        except (KeyError, AttributeError):
            if kupu_library_tool is not None:
                style_whitelist = kupu_library_tool.getStyleWhitelist()
            else:
                style_whitelist = []
        results['valid_inline_styles'] = ','.join(
            style_whitelist)  # tinymce format

        # Replacing some hardcoded translations
        labels = {}
        labels['label_browseimage'] = translate(_('Image Browser'),
                                                context=request)
        labels['label_browselink'] = translate(_('Link Browser'),
                                               context=request)
        labels['label_addnewimage'] = translate(_('Add new Image'),
                                                context=request)
        labels['label_addnewfile'] = translate(_('Add new File'),
                                               context=request)
        labels['label_styles'] = translate(_('(remove style)'),
                                           context=request)
        labels['label_paragraph'] = translate(_('Normal paragraph'),
                                              context=request)
        labels['label_plain_cell'] = translate(_('Plain cell'),
                                               context=request)
        labels['label_style_ldots'] = translate(_('Style...'), context=request)
        labels['label_text'] = translate(_('Text'), context=request)
        labels['label_tables'] = translate(_('Tables'), context=request)
        labels['label_selection'] = translate(_('Selection'), context=request)
        labels['label_lists'] = translate(_('Lists'), context=request)
        labels['label_print'] = translate(_('Print'), context=request)
        labels['label_no_items'] = translate(_('No items in this folder'),
                                             context=request)
        labels['label_no_anchors'] = translate(_('No anchors in this page'),
                                               context=request)
        labels['label_browser'] = translate(_('Browser'), context=request)
        labels['label_shortcuts'] = translate(_('Shortcuts'), context=request)
        labels['label_search_results'] = translate(_('Search results:'),
                                                   context=request)
        labels['label_internal_path'] = translate(PMF("you_are_here",
                                                      default="You are here:"),
                                                  context=request)
        results['labels'] = labels

        # Add styles to results
        results['styles'] = []
        table_styles = []
        if not redefine_parastyles:
            if isinstance(self.tablestyles, StringTypes):
                for tablestyle in self.tablestyles.split('\n'):
                    if not tablestyle:
                        # empty line
                        continue
                    tablestylefields = tablestyle.split('|')
                    tablestyletitle = tablestylefields[0]
                    tablestyleid = tablestylefields[1]
                    if tablestyleid == 'plain':
                        # Do not duplicate the default style hardcoded in the
                        # table.htm.pt
                        continue
                    if request is not None:
                        tablestyletitle = translate(_(tablestylefields[0]),
                                                    context=request)
                    results['styles'].append(tablestyletitle + '|table|' +
                                             tablestyleid)
                    table_styles.append(tablestyletitle + '=' + tablestyleid)
            if isinstance(self.styles, StringTypes):
                styles = []
                for style in self.styles.split('\n'):
                    if not style:
                        # empty line
                        continue
                    stylefields = style.split('|')
                    styletitle = stylefields[0]
                    if request is not None:
                        styletitle = translate(_(stylefields[0]),
                                               context=request)
                    merge = styletitle + '|' + '|'.join(stylefields[1:])
                    styles.append(merge)
                results['styles'].extend(styles)
        results['table_styles'] = ';'.join(table_styles)  # tinymce config

        if parastyles is not None:
            results['styles'].extend(parastyles)

        styles = results.pop('styles')

        # Get buttons from control panel
        results['buttons'] = self.getEnabledButtons(context=context)

        # Filter buttons
        if allow_buttons is not None:
            allow_buttons = self.translateButtonsFromKupu(
                context=context, buttons=allow_buttons)
            results['buttons'] = filter(lambda x: x in results['buttons'],
                                        allow_buttons)
        if filter_buttons is not None:
            filter_buttons = self.translateButtonsFromKupu(
                context=context, buttons=filter_buttons)
            results['buttons'] = filter(lambda x: x not in filter_buttons,
                                        results['buttons'])

        # Get valid html elements
        valid_elements = self.getValidElements()
        results['valid_elements'] = ','.join([
            "%s[%s]" % (key, '|'.join(value))
            for key, value in valid_elements.iteritems()
        ])

        # self.customplugins can be None on old migrated sites
        results['customplugins'] = (self.customplugins or "").splitlines()

        # Set toolbar_location
        if self.toolbar_external:
            results['theme_advanced_toolbar_location'] = 'external'
        else:
            results['theme_advanced_toolbar_location'] = 'top'

        if self.autoresize:
            results['theme_advanced_path_location'] = 'none'
            results['theme_advanced_resizing_use_cookie'] = False
            results['theme_advanced_resizing'] = False
            results['autoresize'] = True
        else:
            results['theme_advanced_path_location'] = 'bottom'
            results['theme_advanced_resizing_use_cookie'] = True
            results['theme_advanced_resizing'] = self.resizing
            results['autoresize'] = False

        if '%' in self.editor_width:
            results['theme_advanced_resize_horizontal'] = False
        else:
            results['theme_advanced_resize_horizontal'] = True

        try:
            results['theme_advanced_source_editor_width'] = int(
                self.editor_width)
        except (TypeError, ValueError):
            results['theme_advanced_source_editor_width'] = 600

        try:
            results['theme_advanced_source_editor_height'] = int(
                self.editor_height)
        except (TypeError, ValueError):
            results['theme_advanced_source_editor_height'] = 400

        try:
            results['toolbar_width'] = int(toolbar_width)
        except (TypeError, ValueError):
            results['toolbar_width'] = 440

        portal_state = context.restrictedTraverse('@@plone_portal_state')
        # is_rtl handles every possible setting as far as RTL/LTR is concerned
        # pass that to tinmyce
        results['directionality'] = portal_state.is_rtl() and 'rtl' or 'ltr'

        portal = portal_state.portal()
        portal_url = portal_state.portal_url()
        results['portal_url'] = portal_url
        results['navigation_root_url'] = portal_state.navigation_root_url()

        if self.content_css and self.content_css.strip() != "":
            results['content_css'] = self.content_css
        else:
            results['content_css'] = '/'.join(
                [results['portal_url'],
                 self.getId(), "@@tinymce-getstyle"])

        results['link_using_uids'] = self.link_using_uids
        results['contextmenu'] = self.contextmenu
        results['entity_encoding'] = self.entity_encoding
        results['script_url'] = portal_url + '/tiny_mce_gzip.js'
        results['allow_captioned_images'] = bool(self.allow_captioned_images)
        results['rooted'] = bool(self.rooted or rooted)

        props = getToolByName(portal, 'portal_properties')
        plone_livesearch = props.site_properties.getProperty(
            'enable_livesearch', False)
        livesearch = props.site_properties.getProperty(
            'enable_tinymce_livesearch', plone_livesearch)
        results['livesearch'] = bool(livesearch)

        AVAILABLE_LANGUAGES = set(
            'sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl '
            'ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa '
            'pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr zh-cn zh-tw uk ur cy vi zu'
            .split())

        if 'LANGUAGE' in context.REQUEST:
            if context.REQUEST.LANGUAGE in AVAILABLE_LANGUAGES:
                results['language'] = context.REQUEST.LANGUAGE
            elif context.REQUEST.LANGUAGE[:2] in AVAILABLE_LANGUAGES:
                results['language'] = context.REQUEST.LANGUAGE[:2]
            else:
                results['language'] = "en"
        else:
            results['language'] = "en"

        try:
            results['document_url'] = context.absolute_url()

            obj = context
            while obj is not None:
                if IFolderish.providedBy(obj):
                    if obj.portal_type != 'TempFolder':
                        # do not use portal_factory generated
                        # temporary object for base url.
                        results['document_base_url'] = obj.absolute_url() + "/"
                        break

                # We should never reach this.
                if ISiteRoot.providedBy(obj):
                    results['document_base_url'] = portal_url + "/"
                    results['document_url'] = portal_url
                    break

                obj = aq_parent(aq_inner(obj))

        except AttributeError:
            results['document_base_url'] = portal_url + "/"
            results['document_url'] = portal_url

        # Get Library options
        results[
            'gecko_spellcheck'] = self.libraries_spellchecker_choice == 'browser'

        # Content Browser
        shortcuts_dict = dict(getUtilitiesFor(ITinyMCEShortcut))
        results['link_shortcuts_html'] = []
        results['image_shortcuts_html'] = []
        results['num_of_thumb_columns'] = self.num_of_thumb_columns
        results['thumbnail_size'] = self.thumbnail_size
        results['anchor_selector'] = self.anchor_selector

        for name in self.link_shortcuts:
            results['link_shortcuts_html'].extend(
                shortcuts_dict.get(name).render(context))
        for name in self.image_shortcuts:
            results['image_shortcuts_html'].extend(
                shortcuts_dict.get(name).render(context))

        # init vars specific for "After the Deadline" spellchecker
        mtool = getToolByName(portal, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        results['atd_rpc_id'] = 'Products.TinyMCE-' + (
            member.getId() or '')  # None when Anonymous User
        results['atd_rpc_url'] = "%s/@@" % portal_url
        results['atd_show_types'] = self.libraries_atd_show_types.strip(
        ).replace('\n', ',')
        results[
            'atd_ignore_strings'] = self.libraries_atd_ignore_strings.strip(
            ).replace('\n', ',')

        # generic configuration
        results['mode'] = "exact"
        results['theme'] = "advanced"
        results['skin'] = "plone"
        results['inlinepopups_skin'] = "plonepopup"

        results['body_class'] = "documentContent"
        plone_view = context.restrictedTraverse('@@plone')
        template = None
        if IBrowserDefault.providedBy(context):
            template = context.unrestrictedTraverse(context.getLayout())
        results['body_class'] += ' ' + plone_view.bodyClass(template, template)

        results['body_id'] = "content"
        results['table_firstline_th'] = True
        results['fix_list_elements'] = False
        # allow embed tag if user removes it from
        # list of nasty tags - see #10681
        results['media_strict'] = False
        results['theme_advanced_path'] = False
        results['theme_advanced_toolbar_align'] = "left"

        results['plugins'] = self.getPlugins()
        results['theme_advanced_styles'] = self.getStyles(styles, labels)
        results['theme_advanced_buttons1'], results['theme_advanced_buttons2'], \
            results['theme_advanced_buttons3'], results['theme_advanced_buttons4'] = self.getToolbars(results)

        if self.formats and self.formats.strip():
            results['formats'] = json.loads(self.formats)

        return results
示例#32
0
    def tinymce(self):
        """
        data-pat-tinymce : JSON.stringify({
            relatedItems: {
              vocabularyUrl: config.portal_url +
                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
            },
            tiny: config,
            prependToUrl: 'resolveuid/',
            linkAttribute: 'UID',
            prependToScalePart: '/@@images/image/'
          })
        """

        generator = TinyMCESettingsGenerator(self.context, self.request)
        settings = generator.settings
        folder = aq_inner(self.context)

        # Test if we are currently creating an Archetype object
        if IFactoryTempFolder.providedBy(aq_parent(folder)):
            folder = aq_parent(aq_parent(aq_parent(folder)))
        if not IFolderish.providedBy(folder):
            folder = aq_parent(folder)

        if IPloneSiteRoot.providedBy(folder):
            initial = None
        else:
            initial = IUUID(folder, None)

        portal = get_portal()
        portal_url = portal.absolute_url()
        nav_root = getNavigationRootObject(folder, portal)
        nav_root_url = nav_root.absolute_url()
        current_path = folder.absolute_url()[len(portal_url):]

        image_types = settings.image_objects or []
        folder_types = settings.contains_objects or []

        server_url = self.request.get('SERVER_URL', '')
        site_path = portal_url[len(server_url):]
        configuration = {
            'base_url':
            self.context.absolute_url(),
            'imageTypes':
            image_types,
            'linkAttribute':
            'UID',
            # This is for loading the languages on tinymce
            'loadingBaseUrl':
            '{0}/++plone++static/components/tinymce-builded/'
            'js/tinymce'.format(portal_url),
            'relatedItems': {
                'folderTypes':
                folder_types,
                'rootPath':
                '/'.join(nav_root.getPhysicalPath()) if nav_root else '/',
                'sort_on':
                'sortable_title',
                'sort_order':
                'ascending',
                'vocabularyUrl':
                '{0}/@@getVocabulary?name=plone.app.vocabularies.'
                'Catalog'.format(nav_root_url),
            },
            'prependToScalePart':
            '/@@images/image/',
            'prependToUrl':
            '{0}/resolveuid/'.format(site_path.rstrip('/')),
            'tiny':
            generator.get_tiny_config(),
            'upload': {
                'baseUrl': portal_url,
                'currentPath': current_path,
                'initialFolder': initial,
                'maxFiles': 1,
                'relativePath': '@@fileUpload',
                'showTitle': False,
                'uploadMultiple': False,
            },
        }
        return {'data-pat-tinymce': json.dumps(configuration)}
示例#33
0
    def upload(self):
        """Adds uploaded file"""

        object = aq_inner(self.context)
        if not IFolderish.providedBy(object):
            object = object.getParentNode()

        context = self.context
        request = context.REQUEST
        ctr_tool = getToolByName(self.context, 'content_type_registry')
        id = request['uploadfile'].filename

        content_type = request['uploadfile'].headers["Content-Type"]
        typename = ctr_tool.findTypeName(id, content_type, "")

        # Permission checks based on code by Danny Bloemendaal

        # 1) check if we are allowed to create an Image in folder
        if not typename in [t.id for t in context.getAllowedTypes()]:
            return self.errorMessage(_("Not allowed to upload a file of this type to this folder"))

        # 2) check if the current user has permissions to add stuff
        if not context.portal_membership.checkPermission('Add portal content', context):
            return self.errorMessage(_("You do not have permission to upload files in this folder"))

        # Get an unused filename without path
        id = self.cleanupFilename(id)

        title = request['uploadtitle']
        description = request['uploaddescription']

        newid = context.invokeFactory(type_name=typename, id=id)

        if newid is None or newid == '':
            newid = id

        obj = getattr(context, newid, None)

        # Set title + description.
        # Attempt to use Archetypes mutator if there is one, in case it uses a custom storage

        if title:
            try:
                obj.setTitle(title)
            except AttributeError:
                obj.title = title

        if description:
            try:
                obj.setDescription(description)
            except AttributeError:
                obj.description = description

        # set primary field
        pf = obj.getPrimaryField()
        pf.set(obj, request['uploadfile'])

        if not obj:
            return self.errorMessage(_("Could not upload the file"))

        obj.reindexObject()

        utility = getUtility(ITinyMCE)
        if utility.link_using_uids:
            return self.okMessage("resolveuid/%s" % (uuidFor(obj)))
        return self.okMessage("%s" % (obj.absolute_url()))
示例#34
0
    def getConfiguration(self, context=None, field=None, request=None):
        """Return configuration as a dictionary

        :param field: Dexterity or Archetypes Field instance

        :param context: The TinyMCE editor content items

        :return: JSON string of the TinyMCE configuration for this field
        """
        results = {}

        # Get widget attributes
        widget = getattr(field, 'widget', None)
        filter_buttons = getattr(widget, 'filter_buttons', None)
        allow_buttons = getattr(widget, 'allow_buttons', None)
        redefine_parastyles = getattr(widget, 'redefine_parastyles', None)
        parastyles = getattr(widget, 'parastyles', None)
        rooted = getattr(widget, 'rooted', False)
        toolbar_width = getattr(widget, 'toolbar_width', self.toolbar_width)

        # Get safe html transform
        safe_html = getattr(getToolByName(self, 'portal_transforms'), 'safe_html')

        # Get kupu library tool filter
        # Settings are stored on safe_html transform in Plone 4 and
        # on kupu tool in Plone 3.
        kupu_library_tool = getToolByName(self, 'kupu_library_tool', None)

        # Remove to be stripped attributes
        try:
            style_whitelist = safe_html.get_parameter_value('style_whitelist')
        except (KeyError, AttributeError):
            if kupu_library_tool is not None:
                style_whitelist = kupu_library_tool.getStyleWhitelist()
            else:
                style_whitelist = []
        results['valid_inline_styles'] = ','.join(style_whitelist)  # tinymce format

        # Replacing some hardcoded translations
        labels = {}
        labels['label_browseimage'] = translate(_('Image Browser'), context=request)
        labels['label_browselink'] = translate(_('Link Browser'), context=request)
        labels['label_addnewimage'] = translate(_('Add new Image'), context=request)
        labels['label_addnewfile'] = translate(_('Add new File'), context=request)
        labels['label_styles'] = translate(_('(remove style)'), context=request)
        labels['label_paragraph'] = translate(_('Normal paragraph'), context=request)
        labels['label_plain_cell'] = translate(_('Plain cell'), context=request)
        labels['label_style_ldots'] = translate(_('Style...'), context=request)
        labels['label_text'] = translate(_('Text'), context=request)
        labels['label_tables'] = translate(_('Tables'), context=request)
        labels['label_selection'] = translate(_('Selection'), context=request)
        labels['label_lists'] = translate(_('Lists'), context=request)
        labels['label_print'] = translate(_('Print'), context=request)
        labels['label_no_items'] = translate(_('No items in this folder'), context=request)
        labels['label_no_anchors'] = translate(_('No anchors in this page'), context=request)
        labels['label_browser'] = translate(_('Browser'), context=request)
        labels['label_shortcuts'] = translate(_('Shortcuts'), context=request)
        labels['label_search_results'] = translate(_('Search results:'), context=request)
        labels['label_internal_path'] = translate(PMF("you_are_here", default="You are here:"), context=request)
        results['labels'] = labels

        # Add styles to results
        results['styles'] = []
        table_styles = []
        if not redefine_parastyles:
            if isinstance(self.tablestyles, StringTypes):
                for tablestyle in self.tablestyles.split('\n'):
                    if not tablestyle:
                        # empty line
                        continue
                    tablestylefields = tablestyle.split('|')
                    tablestyletitle = tablestylefields[0]
                    tablestyleid = tablestylefields[1]
                    if tablestyleid == 'plain':
                        # Do not duplicate the default style hardcoded in the
                        # table.htm.pt
                        continue
                    if request is not None:
                        tablestyletitle = translate(_(tablestylefields[0]), context=request)
                    results['styles'].append(tablestyletitle + '|table|' + tablestyleid)
                    table_styles.append(tablestyletitle + '=' + tablestyleid)
            if isinstance(self.styles, StringTypes):
                styles = []
                for style in self.styles.split('\n'):
                    if not style:
                        # empty line
                        continue
                    stylefields = style.split('|')
                    styletitle = stylefields[0]
                    if request is not None:
                        styletitle = translate(_(stylefields[0]), context=request)
                    merge = styletitle + '|' + '|'.join(stylefields[1:])
                    styles.append(merge)
                results['styles'].extend(styles)
        results['table_styles'] = ';'.join(table_styles)  # tinymce config

        if parastyles is not None:
            results['styles'].extend(parastyles)

        styles = results.pop('styles')

        # Get buttons from control panel
        results['buttons'] = self.getEnabledButtons(context=context)

        # Filter buttons
        if allow_buttons is not None:
            allow_buttons = self.translateButtonsFromKupu(context=context, buttons=allow_buttons)
            results['buttons'] = filter(lambda x: x in results['buttons'], allow_buttons)
        if filter_buttons is not None:
            filter_buttons = self.translateButtonsFromKupu(context=context, buttons=filter_buttons)
            results['buttons'] = filter(lambda x: x not in filter_buttons, results['buttons'])

        # Get valid html elements
        valid_elements = self.getValidElements()
        results['valid_elements'] = ','.join(["%s[%s]" % (key, '|'.join(value)) for key, value in valid_elements.iteritems()])

        # self.customplugins can be None on old migrated sites
        results['customplugins'] = (self.customplugins or "").splitlines()

        # Set toolbar_location
        if self.toolbar_external:
            results['theme_advanced_toolbar_location'] = 'external'
        else:
            results['theme_advanced_toolbar_location'] = 'top'

        if self.autoresize:
            results['theme_advanced_path_location'] = 'none'
            results['theme_advanced_resizing_use_cookie'] = False
            results['theme_advanced_resizing'] = False
            results['autoresize'] = True
        else:
            results['theme_advanced_path_location'] = 'bottom'
            results['theme_advanced_resizing_use_cookie'] = True
            results['theme_advanced_resizing'] = self.resizing
            results['autoresize'] = False

        if '%' in self.editor_width:
            results['theme_advanced_resize_horizontal'] = False
        else:
            results['theme_advanced_resize_horizontal'] = True

        try:
            results['theme_advanced_source_editor_width'] = int(self.editor_width)
        except (TypeError, ValueError):
            results['theme_advanced_source_editor_width'] = 600

        try:
            results['theme_advanced_source_editor_height'] = int(self.editor_height)
        except (TypeError, ValueError):
            results['theme_advanced_source_editor_height'] = 400

        try:
            results['toolbar_width'] = int(toolbar_width)
        except (TypeError, ValueError):
            results['toolbar_width'] = 440

        portal_state = context.restrictedTraverse('@@plone_portal_state')
        # is_rtl handles every possible setting as far as RTL/LTR is concerned
        # pass that to tinmyce
        results['directionality'] = portal_state.is_rtl() and 'rtl' or 'ltr'

        portal = portal_state.portal()
        portal_url = portal_state.portal_url()
        results['portal_url'] = portal_url
        results['navigation_root_url'] = portal_state.navigation_root_url()

        if self.content_css and self.content_css.strip() != "":
            results['content_css'] = self.content_css
        else:
            results['content_css'] = '/'.join([
                results['portal_url'],
                self.getId(),
                "@@tinymce-getstyle"])

        results['link_using_uids'] = self.link_using_uids
        results['contextmenu'] = self.contextmenu
        results['entity_encoding'] = self.entity_encoding
        results['script_url'] = portal_url + '/tiny_mce_gzip.js'
        results['allow_captioned_images'] = bool(self.allow_captioned_images)
        results['rooted'] = bool(self.rooted or rooted)

        props = getToolByName(portal, 'portal_properties')
        livesearch = props.site_properties.getProperty('enable_livesearch', False)
        results['livesearch'] = bool(livesearch)

        AVAILABLE_LANGUAGES = set(
        'sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl '
        'ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa '
        'pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr zh-cn zh-tw uk ur cy vi zu'.split())

        if 'LANGUAGE' in context.REQUEST:
            if context.REQUEST.LANGUAGE in AVAILABLE_LANGUAGES:
                results['language'] = context.REQUEST.LANGUAGE
            elif context.REQUEST.LANGUAGE[:2] in AVAILABLE_LANGUAGES:
                results['language'] = context.REQUEST.LANGUAGE[:2]
            else:
                results['language'] = "en"
        else:
            results['language'] = "en"

        try:
            results['document_url'] = context.absolute_url()

            obj = context
            while obj is not None:
                if IFolderish.providedBy(obj):
                    if obj.portal_type != 'TempFolder':
                        # do not use portal_factory generated
                        # temporary object for base url.
                        results['document_base_url'] = obj.absolute_url() + "/"
                        break

                # We should never reach this.
                if ISiteRoot.providedBy(obj):
                    results['document_base_url'] = portal_url + "/"
                    results['document_url'] = portal_url
                    break

                obj = aq_parent(aq_inner(obj))

        except AttributeError:
            results['document_base_url'] = portal_url + "/"
            results['document_url'] = portal_url

        # Get Library options
        results['gecko_spellcheck'] = self.libraries_spellchecker_choice == 'browser'

        # Content Browser
        shortcuts_dict = dict(getUtilitiesFor(ITinyMCEShortcut))
        results['link_shortcuts_html'] = []
        results['image_shortcuts_html'] = []
        results['num_of_thumb_columns'] = self.num_of_thumb_columns
        results['thumbnail_size'] = self.thumbnail_size
        results['anchor_selector'] = self.anchor_selector

        for name in self.link_shortcuts:
            results['link_shortcuts_html'].extend(shortcuts_dict.get(name).render(context))
        for name in self.image_shortcuts:
            results['image_shortcuts_html'].extend(shortcuts_dict.get(name).render(context))

        # init vars specific for "After the Deadline" spellchecker
        mtool = getToolByName(portal, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        results['atd_rpc_id'] = 'Products.TinyMCE-' + (member.getId() or '')  # None when Anonymous User
        results['atd_rpc_url'] = "%s/@@" % portal_url
        results['atd_show_types'] = self.libraries_atd_show_types.strip().replace('\n', ',')
        results['atd_ignore_strings'] = self.libraries_atd_ignore_strings.strip().replace('\n', ',')

        # generic configuration
        results['mode'] = "exact"
        results['theme'] = "advanced"
        results['skin'] = "plone"
        results['inlinepopups_skin'] = "plonepopup"
        results['body_class'] = "documentContent"
        results['body_id'] = "content"
        results['table_firstline_th'] = True
        results['fix_list_elements'] = False
        # allow embed tag if user removes it from
        # list of nasty tags - see #10681
        results['media_strict'] = False
        results['theme_advanced_path'] = False
        results['theme_advanced_toolbar_align'] = "left"

        results['plugins'] = self.getPlugins()
        results['theme_advanced_styles'] = self.getStyles(styles, labels)
        results['theme_advanced_buttons1'], results['theme_advanced_buttons2'], \
            results['theme_advanced_buttons3'], results['theme_advanced_buttons4'] = self.getToolbars(results)

        if self.formats and self.formats.strip():
            results['formats'] = json.loads(self.formats)

        return results
示例#35
0
    def getConfiguration(self, context=None, field=None, request=None, script_url=None):
        """Return JSON configuration that is passed to javascript tinymce constructor"""
        results = {}

        # Get widget attributes
        widget = getattr(field, 'widget', None)
        filter_buttons = getattr(widget, 'filter_buttons', None)
        allow_buttons = getattr(widget, 'allow_buttons', None)
        redefine_parastyles = getattr(widget, 'redefine_parastyles', None)
        parastyles = getattr(widget, 'parastyles', None)
        rooted = getattr(widget, 'rooted', False)
        toolbar_width = getattr(widget, 'toolbar_width', self.toolbar_width)

        # Get safe html transform
        safe_html = getattr(getToolByName(self, 'portal_transforms'), 'safe_html')

        # Get kupu library tool filter
        # Settings are stored on safe_html transform in Plone 4 and
        # on kupu tool in Plone 3.
        kupu_library_tool = getToolByName(self, 'kupu_library_tool', None)

        # Remove to be stripped attributes
        try:
            style_whitelist = safe_html.get_parameter_value('style_whitelist')
        except (KeyError, AttributeError):
            if kupu_library_tool is not None:
                style_whitelist = kupu_library_tool.getStyleWhitelist()
            else:
                style_whitelist = []
        results['valid_inline_styles'] = ','.join(style_whitelist)  # tinymce format

        # Replacing some hardcoded translations
        labels = {}
        labels['label_styles'] = translate(_('(remove style)'), context=request)
        labels['label_paragraph'] = translate(_('Normal paragraph'), context=request)
        labels['label_plain_cell'] = translate(_('Plain cell'), context=request)
        labels['label_style_ldots'] = translate(_('Style...'), context=request)
        labels['label_text'] = translate(_('Text'), context=request)
        labels['label_tables'] = translate(_('Tables'), context=request)
        labels['label_selection'] = translate(_('Selection'), context=request)
        labels['label_lists'] = translate(_('Lists'), context=request)
        labels['label_print'] = translate(_('Print'), context=request)
        labels['label_no_items'] = translate(_('No items in this folder'), context=request)
        labels['label_no_anchors'] = translate(_('No anchors in this page'), context=request)
        labels['label_browser'] = translate(_('Browser'), context=request)
        labels['label_shortcuts'] = translate(_('Shortcuts'), context=request)
        labels['label_search_results'] = translate(_('Search results:'), context=request)
        labels['label_internal_path'] = translate(_('You are here:'), context=request)
        results['labels'] = labels

        # Add styles to results
        results['styles'] = []
        table_styles = []
        if not redefine_parastyles:
            if isinstance(self.tablestyles, StringTypes):
                for tablestyle in self.tablestyles.split('\n'):
                    if not tablestyle:
                        # empty line
                        continue
                    tablestylefields = tablestyle.split('|')
                    tablestyletitle = tablestylefields[0]
                    tablestyleid = tablestylefields[1]
                    if tablestyleid == 'plain':
                        # Do not duplicate the default style hardcoded in the
                        # table.htm.pt
                        continue
                    if request is not None:
                        tablestyletitle = translate(_(tablestylefields[0]), context=request)
                    results['styles'].append(tablestyletitle + '|table|' + tablestyleid)
                    table_styles.append(tablestyletitle + '=' + tablestyleid)
            if isinstance(self.styles, StringTypes):
                styles = []
                for style in self.styles.split('\n'):
                    if not style:
                        # empty line
                        continue
                    stylefields = style.split('|')
                    styletitle = stylefields[0]
                    if request is not None:
                        styletitle = translate(_(stylefields[0]), context=request)
                    merge = styletitle + '|' + '|'.join(stylefields[1:])
                    styles.append(merge)
                results['styles'].extend(styles)
        results['table_styles'] = ';'.join(table_styles)  # tinymce config

        if parastyles is not None:
            results['styles'].extend(parastyles)

        # Get buttons from control panel
        results['buttons'] = self.getEnabledButtons(context=context)

        # Filter buttons
        if allow_buttons is not None:
            allow_buttons = self.translateButtonsFromKupu(context=context, buttons=allow_buttons)
            results['buttons'] = filter(lambda x: x in results['buttons'], allow_buttons)
        if filter_buttons is not None:
            filter_buttons = self.translateButtonsFromKupu(context=context, buttons=filter_buttons)
            results['buttons'] = filter(lambda x: x not in filter_buttons, results['buttons'])

        # Get valid html elements
        valid_elements = self.getValidElements()
        results['valid_elements'] = ','.join(["%s[%s]" % (key, '|'.join(value)) for key, value in valid_elements.iteritems()])

        # Set toolbar_location
        if self.toolbar_external:
            results['theme_advanced_toolbar_location'] = 'external'
        else:
            results['theme_advanced_toolbar_location'] = 'top'

        if self.autoresize:
            results['theme_advanced_path_location'] = 'none'
            results['theme_advanced_resizing_use_cookie'] = False
            results['theme_advanced_resizing'] = False
            results['autoresize'] = True
        else:
            results['theme_advanced_path_location'] = 'bottom'
            results['theme_advanced_resizing_use_cookie'] = True
            results['theme_advanced_resizing'] = self.resizing
            results['autoresize'] = False

        if '%' in self.editor_width:
            results['theme_advanced_resize_horizontal'] = False
        else:
            results['theme_advanced_resize_horizontal'] = True

        try:
            results['theme_advanced_source_editor_width'] = int(self.editor_width)
        except (TypeError, ValueError):
            results['theme_advanced_source_editor_width'] = 600

        try:
            results['theme_advanced_source_editor_height'] = int(self.editor_height)
        except (TypeError, ValueError):
            results['theme_advanced_source_editor_height'] = 400

        try:
            results['toolbar_width'] = int(toolbar_width)
        except (TypeError, ValueError):
            results['toolbar_width'] = 440

        if self.directionality == 'auto':
            language = context.Language()
            if not language:
                portal_properties = getToolByName(context, "portal_properties")
                site_properties = portal_properties.site_properties
                language = site_properties.getProperty('default_language',
                                                       None)
            directionality = (language[:2] in RIGHT_TO_LEFT) and 'rtl' or 'ltr'
        else:
            directionality = self.directionality
        results['directionality'] = directionality

        if self.content_css and self.content_css.strip() != "":
            results['content_css'] = self.content_css
        else:
            results['content_css'] = self.absolute_url() + """/@@tinymce-getstyle"""

        results['link_using_uids'] = self.link_using_uids
        results['contextmenu'] = self.contextmenu
        if script_url:
            results['script_url'] = script_url

        if self.allow_captioned_images:
            results['allow_captioned_images'] = True
        else:
            results['allow_captioned_images'] = False

        if self.rooted or rooted:
            results['rooted'] = True
        else:
            results['rooted'] = False


        results['entity_encoding'] = self.entity_encoding

        portal = getUtility(ISiteRoot)
        results['portal_url'] = aq_inner(portal).absolute_url()
        nav_root = getNavigationRootObject(context, portal)
        results['navigation_root_url'] = nav_root.absolute_url()

        props = getToolByName(self, 'portal_properties')
        livesearch = props.site_properties.getProperty('enable_livesearch', False)
        if livesearch:
            results['livesearch'] = True
        else:
            results['livesearch'] = False

        AVAILABLE_LANGUAGES = set(
        'sq ar hy az eu be bn nb bs br bg ca ch zh hr cs da dv nl en et fi fr gl '
        'ka de el gu he hi hu is id ia it ja ko lv lt lb mk ms ml mn se no nn fa '
        'pl pt ps ro ru sc sr ii si sk sl es sv ta tt te th tr tw uk ur cy vi zu'.split())

        if 'LANGUAGE' in context.REQUEST:
            results['language'] = context.REQUEST.LANGUAGE[:2]
            if results['language'] not in AVAILABLE_LANGUAGES:
                results['language'] = "en"
        else:
            results['language'] = "en"

        try:
            results['document_url'] = context.absolute_url()
            if getattr(aq_base(context), 'checkCreationFlag', None):
                parent = aq_parent(aq_inner(context))
                if context.checkCreationFlag():
                    parent = aq_parent(aq_parent(parent))
                    results['document_base_url'] = parent.absolute_url() + "/"
                else:
                    if IFolderish.providedBy(context):
                        results['document_base_url'] = context.absolute_url() + "/"
                    else:
                        results['document_base_url'] = parent.absolute_url() + "/"
            else:
                results['document_base_url'] = results['portal_url'] + "/"
        except AttributeError:
            results['document_base_url'] = results['portal_url'] + "/"
            results['document_url'] = results['portal_url']

        # Get Library options
        results['gecko_spellcheck'] = self.libraries_spellchecker_choice == 'browser'

        # Content Browser
        shortcuts_dict = dict(getUtilitiesFor(ITinyMCEShortcut))
        results['link_shortcuts_html'] = []
        results['image_shortcuts_html'] = []
        results['num_of_thumb_columns'] = self.num_of_thumb_columns
        results['thumbnail_size'] = self.thumbnail_size

        for name in self.link_shortcuts:
            results['link_shortcuts_html'].extend(shortcuts_dict.get(name).render(context))
        for name in self.image_shortcuts:
            results['image_shortcuts_html'].extend(shortcuts_dict.get(name).render(context))

        # init vars specific for "After the Deadline" spellchecker
        mtool = getToolByName(portal, 'portal_membership')
        member = mtool.getAuthenticatedMember()
        results['atd_rpc_id'] = 'Products.TinyMCE-' + (member.getId() or '')  # None when Anonymous User
        results['atd_rpc_url'] = "%s/@@" % portal.absolute_url()
        results['atd_show_types'] = self.libraries_atd_show_types.strip().replace('\n', ',')
        results['atd_ignore_strings'] = self.libraries_atd_ignore_strings.strip().replace('\n', ',')

        # generic configuration
        results['mode'] = "exact"
        results['theme'] = "advanced"
        results['skin'] = "plone"
        results['inlinepopups_skin'] = "plonepopup"
        results['body_class'] = "documentContent"
        results['body_id'] = "content"
        results['table_firstline_th'] = True
        results['force_span_wrappers'] = True
        results['fix_list_elements'] = False
        results['theme_advanced_path'] = False
        results['theme_advanced_toolbar_align'] = "left"

        results['plugins'] = self.getPlugins()
        results['theme_advanced_styles'] = self.getStyles(results)
        results['theme_advanced_buttons1'], results['theme_advanced_buttons2'], \
            results['theme_advanced_buttons3'], results['theme_advanced_buttons4'] = self.getToolbars(results)

        return json.dumps(results)
示例#36
0
    def upload(self):
        """Adds uploaded file.

        Required params: uploadfile, uploadtitle, uploaddescription
        """
        context = aq_inner(self.context)
        if not IFolderish.providedBy(context):
            context = aq_parent(context)

        request = context.REQUEST
        ctr_tool = getToolByName(context, 'content_type_registry')
        utility = getToolByName(context, 'portal_tinymce')

        id = request['uploadfile'].filename
        content_type = request['uploadfile'].headers["Content-Type"]
        typename = ctr_tool.findTypeName(id, content_type, "")

        # Permission checks based on code by Danny Bloemendaal

        # 1) check if the current user has permissions to add stuff
        if not context.portal_membership.checkPermission(
                'Add portal content', context):
            return self.errorMessage(
                "You do not have permission to upload files in this folder")

        # 2) check image types uploadable in folder.
        #    priority is to content_type_registry image type
        allowed_types = [t.id for t in context.getAllowedTypes()]
        if typename in allowed_types:
            uploadable_types = [typename]
        else:
            uploadable_types = []

        if content_type.split('/')[0] == 'image':
            image_portal_types = utility.imageobjects.split('\n')
            uploadable_types += [
                t for t in image_portal_types
                if t in allowed_types and t not in uploadable_types
            ]

        # Get an unused filename without path
        id = self.cleanupFilename(id)

        for metatype in uploadable_types:
            try:
                newid = context.invokeFactory(type_name=metatype, id=id)
                if newid is None or newid == '':
                    newid = id
                break
            except ValueError:
                continue
            except BadRequest:
                return self.errorMessage(_("Bad filename, please rename."))
        else:
            return self.errorMessage(
                _("Not allowed to upload a file of this type to this folder"))

        obj = getattr(context, newid, None)

        # Set title + description.
        # Attempt to use Archetypes mutator if there is one, in case it uses
        # a custom storage
        title = request['uploadtitle']
        description = request['uploaddescription']

        if title:
            try:
                obj.setTitle(title)
            except AttributeError:
                obj.title = title

        if description:
            try:
                obj.setDescription(description)
            except AttributeError:
                obj.description = description

        if HAS_DEXTERITY and IDexterityContent.providedBy(obj):
            if not self.setDexterityImage(obj):
                return self.errorMessage(
                    _("The content-type '%s' has no image-field!" % metatype))
        else:
            # set primary field
            pf = obj.getPrimaryField()
            pf.set(obj, request['uploadfile'])

        if not obj:
            return self.errorMessage("Could not upload the file")

        obj.reindexObject()
        folder = obj.aq_parent.absolute_url()

        if utility.link_using_uids:
            path = "resolveuid/%s" % (uuidFor(obj))
        else:
            path = obj.absolute_url()
        return self.okMessage(path, folder)
示例#37
0
    def tinymce(self):
        """
        data-pat-tinymce : JSON.stringify({
            relatedItems: {
              vocabularyUrl: config.portal_url +
                '/@@getVocabulary?name=plone.app.vocabularies.Catalog'
            },
            rel_upload_path: '@@fileUpload',
            folder_url: config.document_base_url,
            tiny: config,
            prependToUrl: 'resolveuid/',
            linkAttribute: 'UID',
            prependToScalePart: '/@@images/image/'
          })
        """
        registry = getUtility(IRegistry)
        settings = registry.forInterface(ITinyMCESchema, prefix="plone")
        config = {
            'portal_url': get_portal_url(self.context),
            'document_base_url': self.context.absolute_url()
        }

        folder = self.context
        if not IFolderish.providedBy(self.context):
            folder = aq_parent(self.context)
        if IPloneSiteRoot.providedBy(folder):
            initial = None
        else:
            initial = IUUID(folder, None)
        current_path = folder.absolute_url()[len(config['portal_url']):]

        # Check if theme has a custom content css
        portal = getSite()
        # Volatile attribute to cache the current theme
        if hasattr(portal, '_v_currentTheme'):
            themeObj = portal._v_currentTheme
        else:
            theme = getCurrentTheme()
            themeObj = getTheme(theme)
            portal._v_currentTheme = themeObj
        cache = component.queryUtility(ram.IRAMCache)
        content_css = None
        if isThemeEnabled(self.request):
            themeObj = cache.query(
                'plone.currentTheme',
                key=dict(prefix='theme'),
                default=None)
            if themeObj is None:
                theme = getCurrentTheme()
                themeObj = getTheme(theme)
                cache.set(
                    themeObj,
                    'plone.currentTheme',
                    key=dict(prefix='theme'))
            if (themeObj and hasattr(themeObj, 'tinymce_content_css') and
                    themeObj.tinymce_content_css):
                content_css = config['portal_url'] + themeObj.tinymce_content_css

        if content_css is None:
            content_css = settings.content_css

        configuration = {
            'relatedItems': format_pattern_settings(
                settings.relatedItems,
                config),
            'upload': {
                'initialFolder': initial,
                'currentPath': current_path,
                'baseUrl': folder.absolute_url(),
                'relativePath': format_pattern_settings(
                    settings.rel_upload_path,
                    config),
                'uploadMultiple': False,
                'maxFiles': 1,
                'showTitle': False
            },
            'base_url': config['document_base_url'],
            'tiny': {
                'content_css': content_css,
            },
            # This is for loading the languages on tinymce
            'loadingBaseUrl': '++plone++static/components/tinymce-builded/js/tinymce',
            'prependToUrl': 'resolveuid/',
            'linkAttribute': format_pattern_settings(
                settings.linkAttribute,
                config),
            'prependToScalePart': format_pattern_settings(
                settings.prependToScalePart,
                config),
            # XXX need to get this from somewhere...
            'folderTypes': ','.join(['Folder']),
            'imageTypes': ','.join(['Image']),
            # 'anchorSelector': utility.anchor_selector,
            # 'linkableTypes': utility.linkable.replace('\n', ',')
        }

        return {'data-pat-tinymce': json.dumps(configuration)}
示例#38
0
    def replace_text(self, item, mode, fields, source, destination):
        changed = False

        def get_new_value(current_value):
            if type(current_value) == str:
                s = safe_encode(source)
                d = safe_encode(destination)
            else:
                s = safe_unicode(source)
                d = safe_unicode(destination)

            if mode == 'plain':
                new_value = current_value.replace(s, d)
            elif mode == 'regexp':
                new_value = re.sub(s, d, current_value)
            elif mode == 'empty':
                new_value = current_value if current_value else d
            else:
                raise ValueError("Unhandled option for text_replace_mode: %s" % mode)
            return new_value

        for field in fields:
            if field == 'short-name':
                continue

            # validation
            if field == 'pdf_url':
                if not IBibliographicItem.providedBy(item):
                    continue

                current = item.pdf_url
                new = get_new_value(current)
                if current != new:
                    item.pdf_url = new
                    changed = True
            elif field == 'publication_url':
                if not IBibliographicItem.providedBy(item):
                    continue

                current = item.publication_url
                new = get_new_value(current)
                if current != new:
                    item.publication_url = new
                    changed = True
            elif field == 'text':
                if IBaseContent.providedBy(item):
                    at_field = item.getField('text')
                    if not at_field:
                        IStatusMessage(self.request).add("%s has no field: %s" % (item.absolute_url(), field), 'error')
                        continue

                    current = at_field.getAccessor(item)()
                    new = get_new_value(current)
                    if current != new:
                        at_field.getMutator(item)(new)
                        changed = True
                elif base_hasattr(item, 'text'):
                    if isinstance(item.text, RichTextValue):
                        current = item.text.raw
                    else:
                        current = item.text

                    new = get_new_value(current)
                    if current != new:
                        if isinstance(item.text, RichTextValue):
                            rtv = item.text
                            rtv._raw_holder.value = new
                            item.text = rtv
                        else:
                            item.text = new
                        changed = True
            elif field == 'title':
                current = item.Title()
                new = get_new_value(current)
                if current != new:
                    item.setTitle(new)
                    changed = True
            elif field == 'description':
                current = item.Description()
                new = get_new_value(current)
                if current != new:
                    item.setDescription(new)
                    changed = True

        if 'short-name' in fields:
            if IFolderish.providedBy(item):
                IStatusMessage(self.request).add('Mass change of short name is forbidden for folder : %s' % item.absolute_url())
            else:
                current = item.id
                new = str(get_new_value(current))
                if current != new:
                    try:
                        api.content.rename(item, new_id=new)
                        changed = True
                    except CopyError:
                        IStatusMessage(self.request).add('Rename failed : %s' % item.absolute_url())
        elif changed:
                item.reindexObject(idxs=['SearchableText'])

        return changed
示例#39
0
    def getListing(self,
                   filter_portal_types,
                   rooted,
                   document_base_url,
                   upload_type=None,
                   image_types=None):
        """Returns the actual listing"""
        catalog_results = []
        results = {}
        image_types = image_types or []

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        if INavigationRoot.providedBy(object) or (rooted == "True"
                                                  and document_base_url[:-1]
                                                  == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = aq_parent(object).absolute_url()

        if rooted == "True":
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        plone_layout = self.context.restrictedTraverse('@@plone_layout', None)
        if plone_layout is None:
            # Plone 3
            plone_view = self.context.restrictedTraverse('@@plone')
            getIcon = lambda brain: plone_view.getIcon(brain).html_tag()
        else:
            # Plone >= 4
            getIcon = lambda brain: plone_layout.getIcon(brain)()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        query = self.listing_base_query.copy()
        query.update({
            'portal_type': filter_portal_types,
            'sort_on': 'getObjPositionInParent',
            'path': {
                'query': path,
                'depth': 1
            }
        })
        for brain in portal_catalog(**query):

            description = ''
            if brain.Description:
                if type(brain.Description) == str:
                    description = unicode(brain.Description, 'utf-8', 'ignore')
                elif type(brain.Description) == unicode:
                    description = brain.Description

            catalog_results.append({
                'id':
                brain.getId,
                'uid':
                brain.UID or None,  # Maybe Missing.Value
                'url':
                brain.getURL(),
                'review_state':
                brain.review_state or None,  # Maybe Missing.Value
                'portal_type':
                brain.portal_type,
                'normalized_type':
                normalizer.normalize(brain.portal_type),
                'title':
                brain.Title == "" and brain.id or brain.Title,
                'icon':
                getIcon(brain),
                'description':
                description,
                'is_folderish':
                brain.is_folderish,
            })

        # add catalog_ressults
        results['items'] = catalog_results

        # decide whether to show the upload new button
        results['upload_allowed'] = False
        if upload_type:
            portal_types = getToolByName(object, 'portal_types')
            fti = getattr(portal_types, upload_type, None)
            if fti is not None:
                results['upload_allowed'] = fti.isConstructionAllowed(object)

        # return results in JSON format
        self.context.REQUEST.response.setHeader("Content-type",
                                                "application/json")
        return json.dumps(results)
示例#40
0
    def getListing(self,
                   filter_portal_types,
                   rooted,
                   document_base_url,
                   upload_type=None):
        """Returns the actual listing"""

        catalog_results = []
        results = {}

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        if INavigationRoot.providedBy(object) or (rooted == "True"
                                                  and document_base_url[:-1]
                                                  == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = aq_parent(object).absolute_url()

        if rooted == "True":
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        for brain in portal_catalog(portal_type=filter_portal_types,
                                    sort_on='getObjPositionInParent',
                                    path={
                                        'query': path,
                                        'depth': 1
                                    }):
            catalog_results.append({
                'id':
                brain.getId,
                'uid':
                brain.UID or None,  # Maybe Missing.Value
                'url':
                brain.getURL(),
                'portal_type':
                brain.portal_type,
                'normalized_type':
                normalizer.normalize(brain.portal_type),
                'title':
                brain.Title == "" and brain.id or brain.Title,
                'icon':
                brain.getIcon,
                'is_folderish':
                brain.is_folderish
            })

        # add catalog_ressults
        results['items'] = catalog_results

        # decide whether to show the upload new button
        results['upload_allowed'] = False
        if upload_type:
            portal_types = getToolByName(object, 'portal_types')
            fti = getattr(portal_types, upload_type, None)
            if fti is not None:
                results['upload_allowed'] = fti.isConstructionAllowed(object)

        # return results in JSON format
        return json.dumps(results)
示例#41
0
    def tinymce(self):
        if api.user.is_anonymous():
            return {}
        generator = CastleTinyMCESettingsGenerator(self.context, self.request)
        settings = generator.settings

        folder = aq_inner(self.context)
        # Test if we are currently creating an Archetype object
        if IFactoryTempFolder.providedBy(aq_parent(folder)):
            folder = aq_parent(aq_parent(aq_parent(folder)))
        if not IFolderish.providedBy(folder):
            folder = aq_parent(folder)

        if IPloneSiteRoot.providedBy(folder):
            initial = None
        else:
            initial = IUUID(folder, None)
        current_path = folder.absolute_url()[len(generator.portal_url):]

        scales = []
        for name, info in sorted(getAllowedSizes().items(),
                                 key=lambda x: x[1][0]):
            scales.append({
                'part':
                name,
                'name':
                name,
                'label':
                '{} ({}x{})'.format(name.capitalize(), info[0], info[1])
            })
        image_types = settings.image_objects or []
        folder_types = settings.contains_objects or []
        configuration = {
            'relatedItems': {
                'vocabularyUrl':
                '%s/@@getVocabulary?name=plone.app.vocabularies.Catalog' %
                (generator.portal_url)
            },
            'upload': {
                'initialFolder': initial,
                'currentPath': current_path,
                'baseUrl': generator.portal_url,
                'relativePath': '@@fileUpload',
                'uploadMultiple': False,
                'maxFiles': 1,
                'showTitle': False
            },
            'base_url':
            self.context.absolute_url(),
            'tiny':
            generator.get_tiny_config(),
            # This is for loading the languages on tinymce
            'loadingBaseUrl':
            '%s/++plone++static/components/tinymce-builded/js/tinymce' %
            generator.portal_url,  # noqa
            'prependToUrl':
            'resolveuid/',
            'linkAttribute':
            'UID',
            'prependToScalePart':
            '/@@images/image/',
            'folderTypes':
            folder_types,
            'imageTypes':
            image_types,
            'scales':
            scales
        }

        return {'data-pat-tinymce': json.dumps(configuration)}
示例#42
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
    def getListing(self,
                   searchtext,
                   rooted=False,
                   document_base_url=None,
                   upload_type=None,
                   image_types=None):
        """Returns the actual listing"""

        # TODO: filter content types to show.
        # eg. show only images...
        intids = getUtility(IIntIds)
        catalog_results = []
        results = {}
        image_types = image_types or []

        object = aq_inner(self.context)
        portal_catalog = getToolByName(object, 'portal_catalog')
        normalizer = getUtility(IIDNormalizer)

        # check if object is a folderish object, if not, get it's parent.
        if not IFolderish.providedBy(object):
            object = aq_parent(object)

        if INavigationRoot.providedBy(object) or \
            (rooted == "True" and \
                document_base_url[:-1] == object.absolute_url()):
            results['parent_url'] = ''
        else:
            results['parent_url'] = aq_parent(object).absolute_url()

        if rooted == "True":
            results['path'] = self.getBreadcrumbs(results['parent_url'])
        else:
            # get all items from siteroot to context (title and url)
            results['path'] = self.getBreadcrumbs()

        plone_layout = self.context.restrictedTraverse('@@plone_layout', None)
        if plone_layout is None:
            # Plone 3
            plone_view = self.context.restrictedTraverse('@@plone')
            getIcon = lambda brain: plone_view.getIcon(brain).html_tag()
        else:
            # Plone >= 4
            getIcon = lambda brain: plone_layout.getIcon(brain)()

        # get all portal types and get information from brains
        path = '/'.join(object.getPhysicalPath())
        query = self.listing_base_query.copy()

        query.update({
            # 'portal_type': filter_portal_types,
            'sort_on': 'getObjPositionInParent',
            'path': {
                'query': path,
                'depth': 1
            }
        })

        if searchtext:
            if '*' not in searchtext:
                searchtext += '*'
            query['SearchableText'] = searchtext,

        for brain in portal_catalog(**query):
            catalog_results.append({
                'id':
                brain.getId,
                'intid':
                intids.getId(brain.getObject()),
                'url':
                brain.getURL(),
                'normalized_type':
                normalizer.normalize(brain.portal_type),
                'title':
                brain.Title == "" and brain.id or brain.Title,
                'icon':
                getIcon(brain),
                'description':
                unicode(brain.Description, 'utf-8', 'ignore'),
                'is_folderish':
                brain.is_folderish,
            })

        # add catalog_ressults
        results['items'] = catalog_results

        # decide whether to show the upload new button
        results['upload_allowed'] = False
        if upload_type:
            portal_types = getToolByName(object, 'portal_types')
            fti = getattr(portal_types, upload_type, None)
            if fti is not None:
                results['upload_allowed'] = fti.isConstructionAllowed(object)

        return results