Back to index

plone3  3.1.7
folderfactories.py
Go to the documentation of this file.
00001 from urllib import quote_plus
00002 
00003 from zope.component import getMultiAdapter, queryMultiAdapter, getAdapters, queryUtility
00004 
00005 from zope.component.interfaces import IFactory
00006 from zope.i18n import translate
00007 from zope.app.container.constraints import checkFactory
00008 from zope.app.publisher.interfaces.browser import AddMenu
00009 
00010 from Acquisition import aq_inner
00011 from Products.Five.browser import BrowserView
00012 
00013 from Products.CMFPlone.interfaces.constrains import ISelectableConstrainTypes
00014 from Products.CMFPlone import PloneMessageFactory as _
00015 
00016 from plone.i18n.normalizer.interfaces import IIDNormalizer
00017 
00018 from plone.memoize.instance import memoize
00019 from plone.memoize.request import memoize_diy_request
00020 
00021 @memoize_diy_request(arg=0)
00022 def _allowedTypes(request, context):
00023     return context.allowedContentTypes()
00024 
00025 class FolderFactoriesView(BrowserView):
00026     """The folder_factories view - show addable types
00027     """
00028     
00029     def __call__(self):
00030         if 'form.button.Add' in self.request.form:
00031             url = self.request.form.get('url')
00032             self.request.response.redirect(url)
00033             return ''
00034         else:
00035             return self.index()
00036     
00037     def can_constrain_types(self):
00038         constrain_types = ISelectableConstrainTypes(self.add_context(), None)
00039         return constrain_types is not None and constrain_types.canConstrainTypes()
00040     
00041     @memoize
00042     def add_context(self):
00043         context_state = getMultiAdapter((self.context, self.request), name='plone_context_state')
00044         return context_state.folder()
00045     
00046     # NOTE: This is also used by plone.app.contentmenu.menu.FactoriesMenu.
00047     # The return value is somewhat dictated by the menu infrastructure, so
00048     # be careful if you change it
00049 
00050     def addable_types(self, include=None):
00051         """Return menu item entries in a TAL-friendly form.
00052         
00053         Pass a list of type ids to 'include' to explicitly allow a list of
00054         types.
00055         """
00056         context = aq_inner(self.context)
00057         request = self.request
00058         
00059         results = []
00060         
00061         portal_state = getMultiAdapter((context, request), name='plone_portal_state')
00062         portal_url = portal_state.portal_url()
00063         
00064         addContext = self.add_context()
00065         baseUrl = addContext.absolute_url()
00066         
00067         allowedTypes = _allowedTypes(request, addContext)
00068         
00069         # XXX: This is calling a pyscript (which we encourage people to customise TTW)
00070         exclude = addContext.getNotAddableTypes()
00071 
00072         # If there is an add view available, use that instead of createObject
00073         # Note: that this depends on the convention that the add view and the
00074         # factory have the same name, and it still only applies where there
00075         # is an FTI in portal_types to begin with. Alas, FTI-less content
00076         # is pretty much a no-go in CMF.
00077         addingview = queryMultiAdapter((addContext, request), name='+')
00078         idnormalizer = queryUtility(IIDNormalizer)
00079         for t in allowedTypes:
00080             typeId = t.getId()
00081             if typeId not in exclude and (include is None or typeId in include):
00082                 cssId = idnormalizer.normalize(typeId)
00083                 cssClass = 'contenttype-%s' % cssId
00084                 factory = t.factory
00085                 if addingview is not None and \
00086                    queryMultiAdapter((addingview, self.request), name=factory) is not None:
00087                     url = '%s/+/%s' % (baseUrl, factory,)
00088                 else:
00089                     url = '%s/createObject?type_name=%s' % (baseUrl, quote_plus(typeId),)
00090                 icon = t.getIcon()
00091                 if icon:
00092                     icon = '%s/%s' % (portal_url, icon)
00093 
00094                 results.append({ 'id'           : typeId,
00095                                  'title'        : t.Title(),
00096                                  'description'  : t.Description(),
00097                                  'action'       : url,
00098                                  'selected'     : False,
00099                                  'icon'         : icon,
00100                                  'extra'        : {'id' : cssId, 'separator' : None, 'class' : cssClass},
00101                                  'submenu'      : None,
00102                                 })
00103 
00104         # Sort the addable content types based on their translated title
00105         results = [(translate(ctype['title'], context=request), ctype) for ctype in results]
00106         results.sort()
00107         results = [ctype[-1] for ctype in results]
00108 
00109         return results