vendor/CMF/1.6.3/CMFCore

view DynamicType.py @ 2:4c712d7bd1d7

Added tag 1.6.3 for changeset 1babb9d61518
author Georges Racinet on purity.racinet.fr <georges@racinet.fr>
date Fri, 09 Sep 2011 12:44:00 +0200
parents
children
line source
1 ##############################################################################
2 #
3 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
4 #
5 # This software is subject to the provisions of the Zope Public License,
6 # Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10 # FOR A PARTICULAR PURPOSE.
11 #
12 ##############################################################################
13 """ DynamicType: Mixin for dynamic properties.
15 $Id$
16 """
18 from urllib import quote
20 from AccessControl import ClassSecurityInfo
21 from Globals import InitializeClass
23 from interfaces.Dynamic import DynamicType as IDynamicType
24 from utils import getToolByName
26 try:
27 from zope.app.publisher.browser import queryDefaultViewName
28 from zope.component import queryMultiAdapter
29 def queryView(obj, name, request):
30 return queryMultiAdapter((obj, request), name=name)
31 except ImportError:
32 # BBB for Zope 2.8
33 from zope.component import queryDefaultViewName, queryView
35 class DynamicType:
36 """
37 Mixin for portal content that allows the object to take on
38 a dynamic type property.
39 """
41 __implements__ = IDynamicType
43 portal_type = None
45 security = ClassSecurityInfo()
47 def _setPortalTypeName(self, pt):
48 """ Set the portal type name.
50 Called by portal_types during construction, records an ID that will be
51 used later to locate the correct ContentTypeInformation.
52 """
53 self.portal_type = pt
55 security.declarePublic('getPortalTypeName')
56 def getPortalTypeName(self):
57 """ Get the portal type name that can be passed to portal_types.
58 """
59 pt = self.portal_type
60 if callable( pt ):
61 pt = pt()
62 return pt
64 # deprecated alias
65 _getPortalTypeName = getPortalTypeName
67 security.declarePublic('getTypeInfo')
68 def getTypeInfo(self):
69 """ Get the TypeInformation object specified by the portal type.
70 """
71 tool = getToolByName(self, 'portal_types', None)
72 if tool is None:
73 return None
74 return tool.getTypeInfo(self) # Can return None.
76 security.declarePublic('getActionInfo')
77 def getActionInfo(self, action_chain, check_visibility=0,
78 check_condition=0):
79 """ Get an Action info mapping specified by a chain of actions.
80 """
81 ti = self.getTypeInfo()
82 if ti:
83 return ti.getActionInfo(action_chain, self, check_visibility,
84 check_condition)
85 else:
86 msg = 'Action "%s" not available for %s' % (
87 action_chain, '/'.join(self.getPhysicalPath()))
88 raise ValueError(msg)
90 # Support for dynamic icons
92 security.declarePublic('getIcon')
93 def getIcon(self, relative_to_portal=0):
94 """
95 Using this method allows the content class
96 creator to grab icons on the fly instead of using a fixed
97 attribute on the class.
98 """
99 ti = self.getTypeInfo()
100 if ti is not None:
101 icon = quote(ti.getIcon())
102 if icon:
103 if relative_to_portal:
104 return icon
105 else:
106 # Relative to REQUEST['BASEPATH1']
107 portal_url = getToolByName( self, 'portal_url' )
108 res = portal_url(relative=1) + '/' + icon
109 while res[:1] == '/':
110 res = res[1:]
111 return res
112 return 'misc_/OFSP/dtmldoc.gif'
114 security.declarePublic('icon')
115 icon = getIcon # For the ZMI
117 def __before_publishing_traverse__(self, arg1, arg2=None):
118 """ Pre-traversal hook.
119 """
120 # XXX hack around a bug(?) in BeforeTraverse.MultiHook
121 REQUEST = arg2 or arg1
123 if REQUEST['REQUEST_METHOD'] not in ('GET', 'POST'):
124 return
126 stack = REQUEST['TraversalRequestNameStack']
127 key = stack and stack[-1] or '(Default)'
129 # if there's a Zope3-style default view name set and the
130 # corresponding view exists, take that in favour of the FTI's
131 # default view
132 if key == '(Default)':
133 viewname = queryDefaultViewName(self, REQUEST)
134 if (viewname and
135 queryView(self, viewname, REQUEST) is not None):
136 stack.append(viewname)
137 REQUEST._hacked_path = 1
138 return
140 ti = self.getTypeInfo()
141 method_id = ti and ti.queryMethodID(key, context=self)
142 if method_id:
143 if key != '(Default)':
144 stack.pop()
145 if method_id != '(Default)':
146 stack.append(method_id)
147 REQUEST._hacked_path = 1
149 InitializeClass(DynamicType)