vendor/CMF/1.6.3/CMFCore

view SkinsTool.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 """Portal skins tool.
15 $Id$
16 """
18 from AccessControl import ClassSecurityInfo
19 from Acquisition import aq_base
20 from DateTime import DateTime
21 from Globals import DTMLFile
22 from Globals import InitializeClass
23 from Globals import PersistentMapping
24 from OFS.DTMLMethod import DTMLMethod
25 from OFS.Folder import Folder
26 from OFS.Image import Image
27 from OFS.ObjectManager import REPLACEABLE
28 from Products.PageTemplates.ZopePageTemplate import ZopePageTemplate
29 from Products.PythonScripts.PythonScript import PythonScript
31 from ActionProviderBase import ActionProviderBase
32 from DirectoryView import base_ignore
33 from DirectoryView import ignore
34 from DirectoryView import ignore_re
35 from interfaces.portal_skins import portal_skins as ISkinsTool
36 from permissions import AccessContentsInformation
37 from permissions import ManagePortal
38 from permissions import View
39 from SkinsContainer import SkinsContainer
40 from utils import _dtmldir
41 from utils import getToolByName
42 from utils import UniqueObject
45 def modifiedOptions():
46 # Remove the existing "Properties" option and add our own.
47 rval = []
48 pos = -1
49 for o in Folder.manage_options:
50 label = o.get('label', None)
51 if label != 'Properties':
52 rval.append(o)
53 rval[1:1] = [{'label':'Properties',
54 'action':'manage_propertiesForm'}]
55 return tuple(rval)
58 class SkinsTool(UniqueObject, SkinsContainer, Folder, ActionProviderBase):
59 """ This tool is used to supply skins to a portal.
60 """
62 __implements__ = (ISkinsTool, SkinsContainer.__implements__,
63 ActionProviderBase.__implements__)
65 id = 'portal_skins'
66 meta_type = 'CMF Skins Tool'
67 _actions = ()
69 allow_any = 0
70 cookie_persistence = 0
71 default_skin = ''
72 request_varname = 'portal_skin'
73 selections = None
75 security = ClassSecurityInfo()
77 manage_options = ( modifiedOptions() +
78 ({ 'label' : 'Overview', 'action' : 'manage_overview' }
79 ,
80 ) + ActionProviderBase.manage_options
81 )
83 def __init__(self):
84 self.selections = PersistentMapping()
86 def _getSelections(self):
87 sels = self.selections
88 if sels is None:
89 # Backward compatibility.
90 self.selections = sels = PersistentMapping()
91 return sels
93 #
94 # ZMI methods
95 #
96 security.declareProtected(ManagePortal, 'manage_overview')
97 manage_overview = DTMLFile( 'explainSkinsTool', _dtmldir )
99 security.declareProtected(ManagePortal, 'manage_propertiesForm')
100 manage_propertiesForm = DTMLFile('dtml/skinProps', globals())
102 # the following two methods override those in FindSupport, to
103 # support marking of objects used in specific skins
104 security.declareProtected(ManagePortal, 'manage_findResult')
105 manage_findResult = DTMLFile('findResult', _dtmldir,
106 management_view='Find')
108 security.declareProtected(ManagePortal, 'manage_findForm')
109 manage_findForm = DTMLFile('findForm', _dtmldir,
110 management_view='Find')
114 security.declareProtected(ManagePortal, 'manage_skinLayers')
115 def manage_skinLayers(self, chosen=(), add_skin=0, del_skin=0,
116 skinname='', skinpath='', REQUEST=None):
117 """ Change the skinLayers.
118 """
119 sels = self._getSelections()
120 if del_skin:
121 for name in chosen:
122 del sels[name]
124 if REQUEST is not None:
125 for key in sels.keys():
126 fname = 'skinpath_%s' % key
127 val = REQUEST[fname]
129 # if val is a list from the new lines field
130 # then munge it back into a comma delimited list
131 # for hysterical reasons
132 if isinstance(val, list):
133 val = ','.join([layer.strip() for layer in val])
135 if sels[key] != val:
136 self.testSkinPath(val)
137 sels[key] = val
139 if add_skin:
140 skinpath = ','.join([layer.strip() for layer in skinpath])
141 self.testSkinPath(skinpath)
142 sels[str(skinname)] = skinpath
144 if REQUEST is not None:
145 return self.manage_propertiesForm(
146 self, REQUEST, management_view='Properties', manage_tabs_message='Skins changed.')
149 security.declareProtected(ManagePortal, 'isFirstInSkin')
150 def isFirstInSkin(self, template_path, skin=None):
151 """
152 Is the specified template the one that would get returned from the current
153 skin?
154 """
155 if skin is None or skin == 'None':
156 skin = self.getDefaultSkin()
157 template = self.restrictedTraverse(template_path)
158 name = template.getId()
159 skin_path = self.getSkinPath(skin)
160 if not skin_path:
161 return 0
162 parts = list(skin_path.split(","))
163 found = ""
164 for part in parts:
165 part = part.strip()
166 if part[0] == "_":
167 continue
168 partob = getattr(self, part, None)
169 if partob:
170 skin_template = getattr(partob.aq_base, name, None)
171 if skin_template:
172 found = skin_template
173 break
174 if found == template:
175 return 1
176 else:
177 return 0
179 security.declareProtected(ManagePortal, 'manage_properties')
180 def manage_properties(self, default_skin='', request_varname='',
181 allow_any=0, chosen=(), add_skin=0,
182 del_skin=0, skinname='', skinpath='',
183 cookie_persistence=0, REQUEST=None):
184 """ Changes portal_skin properties. """
185 self.default_skin = str(default_skin)
186 self.request_varname = str(request_varname)
187 self.allow_any = allow_any and 1 or 0
188 self.cookie_persistence = cookie_persistence and 1 or 0
189 if REQUEST is not None:
190 return self.manage_propertiesForm(
191 self, REQUEST, management_view='Properties', manage_tabs_message='Properties changed.')
193 security.declarePrivate('PUT_factory')
195 def PUT_factory( self, name, typ, body ):
196 """
197 Dispatcher for PUT requests to non-existent IDs. Returns
198 an object of the appropriate type (or None, if we don't
199 know what to do).
200 """
201 major, minor = typ.split('/', 1)
203 if major == 'image':
204 return Image( id=name
205 , title=''
206 , file=''
207 , content_type=typ
208 )
210 if major == 'text':
212 if minor == 'x-python':
213 return PythonScript( id=name )
215 if minor in ('html', 'xml'):
216 return ZopePageTemplate( name )
218 return DTMLMethod( __name__=name )
220 return None
222 # Make the PUT_factory replaceable
223 PUT_factory__replaceable__ = REPLACEABLE
226 security.declarePrivate('testSkinPath')
227 def testSkinPath(self, p):
228 """ Calls SkinsContainer.getSkinByPath().
229 """
230 self.getSkinByPath(p, raise_exc=1)
232 #
233 # 'SkinsContainer' interface methods
234 #
235 security.declareProtected(AccessContentsInformation, 'getSkinPath')
236 def getSkinPath(self, name):
237 """ Convert a skin name to a skin path.
238 """
239 sels = self._getSelections()
240 p = sels.get(name, None)
241 if p is None:
242 if self.allow_any:
243 return name
244 return p # Can be None
246 security.declareProtected(AccessContentsInformation, 'getDefaultSkin')
247 def getDefaultSkin(self):
248 """ Get the default skin name.
249 """
250 return self.default_skin
252 security.declareProtected(AccessContentsInformation, 'getRequestVarname')
253 def getRequestVarname(self):
254 """ Get the variable name to look for in the REQUEST.
255 """
256 return self.request_varname
258 #
259 # UI methods
260 #
261 security.declareProtected(AccessContentsInformation, 'getAllowAny')
262 def getAllowAny(self):
263 '''
264 Used by the management UI. Returns a flag indicating whether
265 users are allowed to use arbitrary skin paths.
266 '''
267 return self.allow_any
269 security.declareProtected(AccessContentsInformation, 'getCookiePersistence')
270 def getCookiePersistence(self):
271 '''
272 Used by the management UI. Returns a flag indicating whether
273 the skins cookie is persistent or not.
274 '''
275 return self.cookie_persistence
277 security.declareProtected(AccessContentsInformation, 'getSkinPaths')
278 def getSkinPaths(self):
279 '''
280 Used by the management UI. Returns the list of skin name to
281 skin path mappings as a sorted list of tuples.
282 '''
283 sels = self._getSelections()
284 rval = []
285 for key, value in sels.items():
286 rval.append((key, value))
287 rval.sort()
288 return rval
290 #
291 # 'portal_skins' interface methods
292 #
293 security.declarePublic('getSkinSelections')
294 def getSkinSelections(self):
295 """ Get the sorted list of available skin names.
296 """
297 sels = self._getSelections()
298 rval = list(sels.keys())
299 rval.sort()
300 return rval
302 security.declareProtected(View, 'updateSkinCookie')
303 def updateSkinCookie(self):
304 """ If needed, updates the skin cookie based on the member preference.
305 """
306 mtool = getToolByName(self, 'portal_membership')
307 utool = getToolByName(self, 'portal_url')
308 member = mtool.getAuthenticatedMember()
309 if hasattr(aq_base(member), 'portal_skin'):
310 mskin = member.portal_skin
311 if mskin:
312 req = self.REQUEST
313 cookie = req.cookies.get(self.request_varname, None)
314 if cookie != mskin:
315 resp = req.RESPONSE
316 portal_path = req['BASEPATH1'] + '/' + utool(1)
318 if not self.cookie_persistence:
319 # *Don't* make the cookie persistent!
320 resp.setCookie(self.request_varname, mskin,
321 path=portal_path)
322 else:
323 expires = ( DateTime( 'GMT' ) + 365 ).rfc822()
324 resp.setCookie( self.request_varname
325 , mskin
326 , path=portal_path
327 , expires=expires
328 )
329 # Ensure updateSkinCookie() doesn't try again
330 # within this request.
331 req.cookies[self.request_varname] = mskin
332 req[self.request_varname] = mskin
333 return 1
334 return 0
336 security.declareProtected(View, 'clearSkinCookie')
337 def clearSkinCookie(self):
338 """ Expire the skin cookie.
339 """
340 req = self.REQUEST
341 resp = req.RESPONSE
342 utool = getToolByName(self, 'portal_url')
343 portal_path = req['BASEPATH1'] + '/' + utool(1)
344 resp.expireCookie(self.request_varname, path=portal_path)
346 security.declareProtected(ManagePortal, 'addSkinSelection')
347 def addSkinSelection(self, skinname, skinpath, test=0, make_default=0):
348 '''
349 Adds a skin selection.
350 '''
351 sels = self._getSelections()
352 skinpath = str(skinpath)
354 # Basic precaution to make sure the stuff we want to ignore in
355 # DirectoryViews gets prevented from ending up in a skin path
356 path_elems = [x.strip() for x in skinpath.split(',')]
357 ignored = base_ignore + ignore
359 for elem in path_elems[:]:
360 if elem in ignored or ignore_re.match(elem):
361 path_elems.remove(elem)
363 skinpath = ','.join(path_elems)
365 if test:
366 self.testSkinPath(skinpath)
367 sels[str(skinname)] = skinpath
368 if make_default:
369 self.default_skin = skinname
371 InitializeClass(SkinsTool)