Back to index

plone3  3.1.7
skins.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2005 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 """Skins tool xml adapters and setup handlers.
00014 
00015 $Id: skins.py 76996 2007-06-24 00:18:49Z hannosch $
00016 """
00017 
00018 from Acquisition import aq_inner
00019 from Acquisition import aq_parent
00020 from zope.component import adapts
00021 
00022 from Products.GenericSetup.interfaces import ISetupEnviron
00023 from Products.GenericSetup.utils import exportObjects
00024 from Products.GenericSetup.utils import importObjects
00025 from Products.GenericSetup.utils import NodeAdapterBase
00026 from Products.GenericSetup.utils import ObjectManagerHelpers
00027 from Products.GenericSetup.utils import XMLAdapterBase
00028 
00029 from Products.CMFCore.interfaces import IDirectoryView
00030 from Products.CMFCore.interfaces import ISkinsTool
00031 from Products.CMFCore.utils import getToolByName
00032 
00033 
00034 class DirectoryViewNodeAdapter(NodeAdapterBase):
00035 
00036     """Node im- and exporter for DirectoryView.
00037     """
00038 
00039     adapts(IDirectoryView, ISetupEnviron)
00040 
00041     def _exportNode(self):
00042         """Export the object as a DOM node.
00043         """
00044         node = self._getObjectNode('object')
00045         node.setAttribute('directory', self.context.getDirPath())
00046         return node
00047 
00048     def _importNode(self, node):
00049         """Import the object from the DOM node.
00050         """
00051         self.context.manage_properties(str(node.getAttribute('directory')))
00052 
00053     node = property(_exportNode, _importNode)
00054 
00055 
00056 class SkinsToolXMLAdapter(XMLAdapterBase, ObjectManagerHelpers):
00057 
00058     """XML im- and exporter for SkinsTool.
00059     """
00060 
00061     adapts(ISkinsTool, ISetupEnviron)
00062 
00063     _LOGGER_ID = 'skins'
00064 
00065     name = 'skins'
00066 
00067     def _exportNode(self):
00068         """Export the object as a DOM node.
00069         """
00070         node = self._getObjectNode('object')
00071         node.setAttribute('default_skin', self.context.default_skin)
00072         node.setAttribute('request_varname', self.context.request_varname)
00073         node.setAttribute('allow_any', str(bool(self.context.allow_any)))
00074         node.setAttribute('cookie_persistence',
00075                           str(bool(self.context.cookie_persistence)))
00076         node.appendChild(self._extractObjects())
00077         node.appendChild(self._extractSkinPaths())
00078 
00079         self._logger.info('Skins tool exported.')
00080         return node
00081 
00082     def _importNode(self, node):
00083         """Import the object from the DOM node.
00084         """
00085         obj = self.context
00086 
00087         if self.environ.shouldPurge():
00088             obj.default_skin = ''
00089             obj.request_varname = 'portal_skin'
00090             obj.allow_any = 0
00091             obj.cookie_persistence = 0
00092             self._purgeObjects()
00093             self._purgeSkinPaths()
00094 
00095         if node.hasAttribute('default_skin'):
00096             obj.default_skin = str(node.getAttribute('default_skin'))
00097         if node.hasAttribute('request_varname'):
00098             obj.request_varname = str(node.getAttribute('request_varname'))
00099         if node.hasAttribute('allow_any'):
00100             allow_any = node.getAttribute('allow_any')
00101             obj.allow_any = int(self._convertToBoolean(allow_any))
00102         if node.hasAttribute('cookie_persistence'):
00103             persistence = node.getAttribute('cookie_persistence')
00104             obj.cookie_persistence = int(self._convertToBoolean(persistence))
00105         self._initObjects(node)
00106         self._initSkinPaths(node)
00107 
00108         self._logger.info('Skins tool imported.')
00109 
00110     def _extractSkinPaths(self):
00111         fragment = self._doc.createDocumentFragment()
00112         for k, v in self.context.getSkinPaths():
00113             node = self._doc.createElement('skin-path')
00114             node.setAttribute('name', k)
00115             for layer in [ l.strip() for l in v.split(',') if l.strip() ]:
00116                 child = self._doc.createElement('layer')
00117                 child.setAttribute('name', layer)
00118                 node.appendChild(child)
00119             fragment.appendChild(node)
00120         return fragment
00121 
00122     def _purgeSkinPaths(self):
00123         self.context._getSelections().clear()
00124 
00125     def _initSkinPaths(self, node):
00126         for child in node.childNodes:
00127             if child.nodeName != 'skin-path':
00128                 continue
00129             path_id = str(child.getAttribute('name'))
00130             if str(child.getAttribute('remove')):
00131                 self._removeSkin(skin_name=path_id)
00132                 continue
00133             if path_id == '*':
00134                 for path_id, path in self.context._getSelections().items():
00135                     path = self._updatePath(path, child)
00136                     self.context.addSkinSelection(path_id, path)
00137             else:
00138                 path = ''
00139                 if child.hasAttribute('based-on'):
00140                     try:
00141                         basename = child.getAttribute('based-on')
00142                         path = self.context._getSelections()[basename]
00143                     except KeyError:
00144                         pass
00145                 if path_id in self.context._getSelections():
00146                     oldpath = self.context._getSelections()[path_id].split(',')
00147                     for layer in oldpath:
00148                         if layer not in path:
00149                             layernode = self._doc.createElement('layer')
00150                             layernode.setAttribute('name', layer)
00151                             if oldpath.index(layer) == 0:
00152                                 layernode.setAttribute('insert-before', '*')
00153                             else:
00154                                 pos = oldpath[oldpath.index(layer)-1]
00155                                 layernode.setAttribute('insert-after', pos)
00156                             child.appendChild(layernode)
00157                 path = self._updatePath(path, child)
00158                 self.context.addSkinSelection(path_id, path)
00159         #
00160         # Purge and rebuild the skin path, now that we have added our stuff.
00161         # Don't bother if no REQUEST is present, e.g. when running unit tests
00162         #
00163         request = getattr(self.context, 'REQUEST', None)
00164         skinnable = aq_parent(aq_inner(self.context))
00165         if request is not None and skinnable is not None:
00166             skinnable.clearCurrentSkin()
00167             skinnable.setupCurrentSkin(request)
00168 
00169     def _updatePath(self, path, node):
00170         path = [ name.strip() for name in path.split(',') if name.strip() ]
00171 
00172         for child in node.childNodes:
00173             if child.nodeName != 'layer':
00174                 continue
00175             layer_name = child.getAttribute('name')
00176             if layer_name in path:
00177                 path.remove(layer_name)
00178 
00179             if child.hasAttribute('insert-before'):
00180                 insert_before = child.getAttribute('insert-before')
00181                 if insert_before == '*':
00182                     path.insert(0, layer_name)
00183                     continue
00184                 else:
00185                     try:
00186                         index = path.index(insert_before)
00187                         path.insert(index, layer_name)
00188                         continue
00189                     except ValueError:
00190                         pass
00191             elif child.hasAttribute('insert-after'):
00192                 insert_after = child.getAttribute('insert-after')
00193                 if insert_after == '*':
00194                     pass
00195                 else:
00196                     try:
00197                         index = path.index(insert_after)
00198                         path.insert(index+1, layer_name)
00199                         continue
00200                     except ValueError:
00201                         pass
00202 
00203             if not child.hasAttribute('remove'):
00204                 path.append(layer_name)
00205 
00206         return str( ','.join(path) )
00207 
00208 
00209     def _removeSkin(self, skin_name=None):
00210         """
00211         Remove a skin from the skinstool
00212         """
00213         skins = self.context.getSkinSelections()
00214         if skin_name in skins:
00215             self.context.manage_skinLayers(chosen=[skin_name], del_skin=1, )
00216 
00217 
00218 def importSkinsTool(context):
00219     """Import skins tool FSDirViews and skin paths from an XML file.
00220     """
00221     site = context.getSite()
00222     tool = getToolByName(site, 'portal_skins')
00223 
00224     importObjects(tool, '', context)
00225 
00226 def exportSkinsTool(context):
00227     """Export skins tool FSDVs and skin paths as an XML file.
00228     """
00229     site = context.getSite()
00230     tool = getToolByName(site, 'portal_skins', None)
00231     if tool is None:
00232         logger = context.getLogger('skins')
00233         logger.info('Nothing to export.')
00234         return
00235 
00236     exportObjects(tool, '', context)