Back to index

plone3  3.1.7
DynamicType.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ DynamicType: Mixin for dynamic properties.
00014 
00015 $Id: DynamicType.py 76996 2007-06-24 00:18:49Z hannosch $
00016 """
00017 
00018 from urllib import quote
00019 
00020 from AccessControl import ClassSecurityInfo
00021 from Globals import InitializeClass
00022 from zope.app.publisher.browser import queryDefaultViewName
00023 from zope.component import queryMultiAdapter
00024 from zope.interface import implements
00025 
00026 from interfaces import IDynamicType
00027 from utils import getToolByName
00028 from interfaces.Dynamic import DynamicType as z2IDynamicType
00029 
00030 
00031 class DynamicType:
00032 
00033     """
00034     Mixin for portal content that allows the object to take on
00035     a dynamic type property.
00036     """
00037 
00038     implements(IDynamicType)
00039     __implements__ = z2IDynamicType
00040 
00041     portal_type = None
00042 
00043     security = ClassSecurityInfo()
00044 
00045     def _setPortalTypeName(self, pt):
00046         """ Set the portal type name.
00047 
00048         Called by portal_types during construction, records an ID that will be
00049         used later to locate the correct ContentTypeInformation.
00050         """
00051         self.portal_type = pt
00052 
00053     security.declarePublic('getPortalTypeName')
00054     def getPortalTypeName(self):
00055         """ Get the portal type name that can be passed to portal_types.
00056         """
00057         pt = self.portal_type
00058         if callable( pt ):
00059             pt = pt()
00060         return pt
00061 
00062     # deprecated alias
00063     _getPortalTypeName = getPortalTypeName
00064 
00065     security.declarePublic('getTypeInfo')
00066     def getTypeInfo(self):
00067         """ Get the TypeInformation object specified by the portal type.
00068         """
00069         tool = getToolByName(self, 'portal_types', None)
00070         if tool is None:
00071             return None
00072         return tool.getTypeInfo(self)  # Can return None.
00073 
00074     security.declarePublic('getActionInfo')
00075     def getActionInfo(self, action_chain, check_visibility=0,
00076                       check_condition=0):
00077         """ Get an Action info mapping specified by a chain of actions.
00078         """
00079         ti = self.getTypeInfo()
00080         if ti:
00081             return ti.getActionInfo(action_chain, self, check_visibility,
00082                                     check_condition)
00083         else:
00084             msg = 'Action "%s" not available for %s' % (
00085                         action_chain, '/'.join(self.getPhysicalPath()))
00086             raise ValueError(msg)
00087 
00088     # Support for dynamic icons
00089 
00090     security.declarePublic('getIcon')
00091     def getIcon(self, relative_to_portal=0):
00092         """
00093         Using this method allows the content class
00094         creator to grab icons on the fly instead of using a fixed
00095         attribute on the class.
00096         """
00097         ti = self.getTypeInfo()
00098         if ti is not None:
00099             icon = quote(ti.getIcon())
00100             if icon:
00101                 if relative_to_portal:
00102                     return icon
00103                 else:
00104                     # Relative to REQUEST['BASEPATH1']
00105                     portal_url = getToolByName( self, 'portal_url' )
00106                     res = portal_url(relative=1) + '/' + icon
00107                     while res[:1] == '/':
00108                         res = res[1:]
00109                     return res
00110         return 'misc_/OFSP/dtmldoc.gif'
00111 
00112     security.declarePublic('icon')
00113     icon = getIcon  # For the ZMI
00114 
00115     def __before_publishing_traverse__(self, arg1, arg2=None):
00116         """ Pre-traversal hook.
00117         """
00118         # XXX hack around a bug(?) in BeforeTraverse.MultiHook
00119         REQUEST = arg2 or arg1
00120 
00121         if REQUEST['REQUEST_METHOD'] not in ('GET', 'POST'):
00122             return
00123 
00124         stack = REQUEST['TraversalRequestNameStack']
00125         key = stack and stack[-1] or '(Default)'
00126 
00127         # if there's a Zope3-style default view name set and the
00128         # corresponding view exists, take that in favour of the FTI's
00129         # default view
00130         if key == '(Default)':
00131             viewname = queryDefaultViewName(self, REQUEST)
00132             if (viewname and
00133                 queryMultiAdapter((self, REQUEST), name=viewname) is not None):
00134                 stack.append(viewname)
00135                 REQUEST._hacked_path = 1
00136                 return
00137 
00138         ti = self.getTypeInfo()
00139         method_id = ti and ti.queryMethodID(key, context=self)
00140         if method_id:
00141             if key != '(Default)':
00142                 stack.pop()
00143             if method_id != '(Default)':
00144                 stack.append(method_id)
00145             REQUEST._hacked_path = 1
00146 
00147 InitializeClass(DynamicType)