[Checkins] SVN: z3ext.skintool/trunk/ Added skin configurable schema

Nikolay Kim fafhrd91 at gmail.com
Wed Jul 15 18:16:15 EDT 2009


Log message for revision 101939:
  Added skin configurable schema

Changed:
  U   z3ext.skintool/trunk/CHANGES.txt
  U   z3ext.skintool/trunk/buildout.cfg
  U   z3ext.skintool/trunk/setup.py
  U   z3ext.skintool/trunk/src/z3ext/skintool/README.txt
  D   z3ext.skintool/trunk/src/z3ext/skintool/configlet.pt
  D   z3ext.skintool/trunk/src/z3ext/skintool/configlet.py
  U   z3ext.skintool/trunk/src/z3ext/skintool/configure.zcml
  U   z3ext.skintool/trunk/src/z3ext/skintool/generations/install.py
  U   z3ext.skintool/trunk/src/z3ext/skintool/interfaces.py
  A   z3ext.skintool/trunk/src/z3ext/skintool/skindatatype.py
  U   z3ext.skintool/trunk/src/z3ext/skintool/subscribers.py
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/__init__.py
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/configure.zcml
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/ftesting.zcml
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/interfaces.py
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/overrides.zcml
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/testbrowser.txt
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/testlayout.pt
  A   z3ext.skintool/trunk/src/z3ext/skintool/tests/tests.py
  D   z3ext.skintool/trunk/src/z3ext/skintool/tests.py
  U   z3ext.skintool/trunk/src/z3ext/skintool/tool.py
  U   z3ext.skintool/trunk/src/z3ext/skintool/zcml.py

-=-
Modified: z3ext.skintool/trunk/CHANGES.txt
===================================================================
--- z3ext.skintool/trunk/CHANGES.txt	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/CHANGES.txt	2009-07-15 22:16:15 UTC (rev 101939)
@@ -2,6 +2,12 @@
 CHANGES
 =======
 
+1.2.0 (Unreleased)
+------------------
+
+- Added skin configurable schema.
+
+
 1.1.3 (2009-04-??)
 ------------------
 

Modified: z3ext.skintool/trunk/buildout.cfg
===================================================================
--- z3ext.skintool/trunk/buildout.cfg	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/buildout.cfg	2009-07-15 22:16:15 UTC (rev 101939)
@@ -26,15 +26,8 @@
 zcml =
   <configure xmlns:zcml="http://namespaces.zope.org/zcml"
              xmlns:browser="http://namespaces.zope.org/browser">
-    <include package="zope.component" file="meta.zcml" />
-    <include package="zope.app.component" file="meta.zcml" />
-    <include package="zope.app.security" file="meta.zcml" />
-    <include package="zope.app.security" />
-    <include package="zope.app.zcmlfiles" />
-
-    <include package="z3c.autoinclude" file="meta.zcml" />
-    <include package="z3ext.skintool" file="meta.zcml" />
-    <include package="z3ext.skintool" />
+    <include package="z3ext.autoinclude" file="meta.zcml" />
+    <includeAllDependencies package="z3ext.skintool" extras="test" />
   </configure>
 
 [i18nall]

Modified: z3ext.skintool/trunk/setup.py
===================================================================
--- z3ext.skintool/trunk/setup.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/setup.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -21,7 +21,7 @@
 def read(*rnames):
     return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
 
-version = '1.1.3dev'
+version = '1.2.0dev'
 
 
 setup(name='z3ext.skintool',
@@ -54,23 +54,27 @@
       namespace_packages=['z3ext'],
       install_requires = ['setuptools',
                           'zope.schema',
-			  'zope.proxy',
+                          'zope.proxy',
                           'zope.component',
                           'zope.interface',
-			  'zope.security',
-			  'zope.configuration',
-			  'zope.lifecycleevent',
-			  'zope.app.intid',
+                          'zope.security',
+                          'zope.configuration',
+                          'zope.lifecycleevent',
+                          'zope.app.intid',
                           'zope.app.component',
-			  'zope.app.publication',
+                          'zope.app.publication',
                           'zope.i18nmessageid',
                           'zope.i18n',
-			  'z3ext.controlpanel',
-			  'z3ext.widget.radio',
-			  'z3ext.widget.checkbox',
+                          'z3ext.controlpanel',
+                          'z3ext.widget.radio',
+                          'z3ext.widget.checkbox',
                           ],
       extras_require = dict(test=['zope.app.testing',
+                                  'zope.app.zcmlfiles',
                                   'zope.testing',
+                                  'zope.testbrowser',
+                                  'z3ext.autoinclude',
+                                  'z3ext.security',
                                   ]),
       include_package_data = True,
       zip_safe = False

Modified: z3ext.skintool/trunk/src/z3ext/skintool/README.txt
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/README.txt	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/README.txt	2009-07-15 22:16:15 UTC (rev 101939)
@@ -7,6 +7,7 @@
   >>> from z3ext.skintool import interfaces, zcml
   >>> from z3ext.skintool.tool import skinToolModified
 
+
   >>> from zope import interface, component, schema
 
 We need site object and request
@@ -17,22 +18,48 @@
   >>> from zope.publisher.browser import TestRequest
   >>> request = TestRequest()
 
+We register skintool configlet
+
+  >>> from zope.configuration import xmlconfig
+  >>> context = xmlconfig.string("""
+  ... <configure xmlns:z3ext="http://namespaces.zope.org/z3ext"
+  ...    xmlns="http://namespaces.zope.org/zope" i18n_domain="z3ext">
+  ...
+  ...    <include package="z3ext.controlpanel" file="meta.zcml" />
+  ...
+  ...    <z3ext:configlet
+  ...      name="portalskin"
+  ...      title="Portal skin"
+  ...      description="Portal skin configuration."
+  ...      class="z3ext.skintool.tool.SkinTool"
+  ...      schema="z3ext.skintool.interfaces.ISkinTool" />
+  ...
+  ... </configure>""")
+
 Now let's define layer and skin
 
-  >>> from zope import interface
+  >>> from zope import interface, schema
   >>> class IMySkin(interface.Interface):
   ...     pass
   >>> class IMyLayer(interface.Interface):
   ...     pass
 
+
+We define skin schema
+
+  >>> class IMySkinSchema(interface.Interface):
+  ...     param1 = schema.TextLine(title=u'Param 1')
+
 Before we can use IMySkin and IMyLayer we should register it in local registry
 
-  >>> zcml.skinDirective(IMySkin, u'myskin', u'My skin', '', ())
+  >>> zcml.skinDirective(IMySkin, u'myskin', u'My skin', '', (), IMySkinSchema)
   >>> zcml.layerDirective(IMyLayer, u'mylayer', u'My layer', '')
 
 Now skin and layer should be listed in vocabulary.
 
+  >>> from zope.schema.vocabulary import getVocabularyRegistry
   >>> from z3ext.skintool.vocabulary import SkinsVocabulary
+  >>> getVocabularyRegistry().register('z3ext skins', SkinsVocabulary())
   >>> voc = SkinsVocabulary()(site)
   >>> term = voc.getTerm(IMySkin)
   >>> term.value == u'myskin'
@@ -43,6 +70,7 @@
   True
 
   >>> from z3ext.skintool.vocabulary import LayersVocabulary
+  >>> getVocabularyRegistry().register('z3ext layers', LayersVocabulary())
   >>> voc = LayersVocabulary()(site)
   >>> term = voc.getTerm(IMyLayer)
   >>> term.value == u'mylayer'
@@ -88,6 +116,15 @@
   >>> IMyLayer.providedBy(request)
   True
 
+We have skin configuration data:
+
+  >>> tool.skinData
+  <z3ext.skintool.skindatatype.SkinData<ui.portalskin.skindata> ...>
+
+And default attributes:
+
+  >>> tool.skinData.param1
+
 Change layers config
 
   >>> tool.layers = []
@@ -130,7 +167,6 @@
   >>> IDefaultLayer.providedBy(request)
   True
 
-
 z3ext:layer directive
 ---------------------
 

Deleted: z3ext.skintool/trunk/src/z3ext/skintool/configlet.pt
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/configlet.pt	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/configlet.pt	2009-07-15 22:16:15 UTC (rev 101939)
@@ -1,53 +0,0 @@
-<tal:block i18n:domain="z3ext.skintool"
-	   tal:define="skins view/listSkins; 
-		       layers view/listLayers;
-		       noForm python: not (skins or layers)">
-  <h1 tal:content="context/__title__"></h1>
-  <div class="z-page-description" tal:content="context/__description__"></div>
-
-  <form action="index.html" method="post" tal:omit-tag="noForm">
-    <div class="z-frame" tal:condition="skins">
-      <h3 i18n:translate="">Skin</h3>
-      <div class="z-page-description" i18n:translate="">Please select portal skin.</div>
-      <ul class="z-listing">
-	<li tal:repeat="item skins">
-	  <div class="z-listing-icon">
-	    <input type="radio" name="skin"
-		   tal:attributes="value item/name; checked item/selected" />
-	  </div>
-	  <div class="z-listing-details">
-	    <span tal:content="item/title"/>
-	    <div tal:content="item/description" />
-	  </div>
-	</li>
-      </ul>
-    </div>
-
-    <div class="z-frame" tal:condition="layers">
-      <h3 i18n:translate="">Layers</h3>
-      <div class="z-page-description" i18n:translate="">Please select layers.</div>
-      <ul class="z-listing">
-	<li tal:repeat="item layers">
-	  <div class="z-listing-icon">
-	    <input type="checkbox" name="layers:list"
-		   tal:attributes="value item/name; checked item/selected" />
-	  </div>
-	  <div class="z-listing-details">
-	    <span tal:content="item/title"></span>
-	    <div tal:content="item/description"></div>
-	  </div>
-	</li>
-      </ul>
-    </div>
-    
-    <div class="z-form-controls" tal:condition="not:noForm">
-      <hr />
-      <input type="submit" name="form.buttons.save" value="Save"
-	     class="z-form-button" i18n:attributes="value" />
-    </div>
-  </form>
-
-  <div class="z-frame" tal:condition="noForm" i18n:translate="">
-    There are no any configurable skins or layers.
-  </div>
-</tal:block>

Deleted: z3ext.skintool/trunk/src/z3ext/skintool/configlet.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/configlet.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/configlet.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -1,71 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-""" 
-
-$Id:  2007-12-12 12:27:02Z fafhrd $
-"""
-from zope import event
-from zope.component import getUtility
-from zope.lifecycleevent import ObjectModifiedEvent
-
-from z3ext.skintool import tool
-from z3ext.skintool.interfaces import _, ISkinTool
-from z3ext.statusmessage.interfaces import IStatusMessage
-
-
-class SkintoolEditForm(object):
-
-    def listSkins(self):
-        skins = []
-        for skin, name, title, description, require \
-                in tool.skins_registry.values():
-            skins.append((title, name, 
-                          {'name': name,
-                           'title': title,
-                           'selected': self.tool.skin == name,
-                           'description': description}))
-        skins.sort()
-
-        skins.insert(0, ('', '', 
-                         {'name': '__no__',
-                          'title': _(u'No skin'),
-                          'selected': self.tool.skin == None,
-                          'description': _(u'Do not use any skin.')}))
-        return [info for t, n, info in skins]
-    
-    def listLayers(self):
-        layers = []
-        for layer, name, title, description in tool.layers_registry.values():
-            layers.append((title, name, 
-                           {'name': name,
-                            'title': title,
-                            'selected': name in self.tool.layers,
-                            'description': description}))
-        layers.sort()
-
-        return [info for t, n, info in layers]
-
-    def update(self):
-        self.tool = getUtility(ISkinTool)
-
-        if 'form.buttons.save' in self.request:
-            skin = self.request.get('skin', '__no__')
-            if skin == '__no__':
-                self.tool.skin = None
-            else:
-                self.tool.skin = skin
-
-            self.tool.layers = self.request.get('layers', [])
-            event.notify(ObjectModifiedEvent(self.tool))
-            IStatusMessage(self.request).add(_(u'Changes has been saved.'))

Modified: z3ext.skintool/trunk/src/z3ext/skintool/configure.zcml
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/configure.zcml	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/configure.zcml	2009-07-15 22:16:15 UTC (rev 101939)
@@ -1,4 +1,4 @@
-<configure 
+<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:i18n="http://namespaces.zope.org/i18n"
    xmlns:z3ext="http://namespaces.zope.org/z3ext"
@@ -25,6 +25,14 @@
      class=".tool.SkinTool"
      schema=".interfaces.ISkinTool" />
 
+  <!-- edit schema -->
+  <z3ext:pagelet
+     name="schema"
+     type="form.subform"
+     for=".interfaces.ISkinTool *"
+     class=".tool.SchemaEditForm"
+     weight="10" />
+
   <!-- translations -->
   <i18n:registerTranslations directory="locales"/>
 

Modified: z3ext.skintool/trunk/src/z3ext/skintool/generations/install.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/generations/install.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/generations/install.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -52,6 +52,6 @@
 
                 if layer in tool.layers_byname:
                     ulayers.append(layer)
-                
+
             skintool.skin = skin
             skintool.layers = ulayers

Modified: z3ext.skintool/trunk/src/z3ext/skintool/interfaces.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/interfaces.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/interfaces.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -57,5 +57,7 @@
         default = [],
         required = False)
 
+    skinData = interface.Attribute('Skin data')
+
     def generate():
         """ generate skin interface """

Added: z3ext.skintool/trunk/src/z3ext/skintool/skindatatype.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/skindatatype.py	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/skindatatype.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,58 @@
+##############################################################################
+#
+# Copyright (c) 2007 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+""" Skin Data metaclass
+
+$Id$
+"""
+import sys
+from zope.schema import getFields
+from persistent import Persistent
+from zope.app.container.contained import Contained
+from zope.schema.fieldproperty import FieldProperty
+
+from interfaces import _
+from z3ext.controlpanel.storage import ConfigletData
+from z3ext.controlpanel.configlettype import DataProperty
+
+from interfaces import _
+
+_marker = object()
+
+
+class SkinDataType(type):
+    """ Metaclass for skin data """
+
+    def __new__(cls, name, schema, class_=None, *args, **kw):
+        cname = 'SkinData<%s>'%name
+        if type(class_) is tuple:
+            bases = class_ + (Persistent, Contained,)
+        elif class_ is not None:
+            bases = (class_, Persistent, Contained)
+        else:
+            bases = (Persistent, Contained,)
+
+        tp = type.__new__(cls, str(cname), bases, {})
+        setattr(sys.modules['z3ext.skintool.skindatatype'], cname, tp)
+
+        return tp
+
+    def __init__(cls, name, schema, class_=None, title='', description=''):
+        for f_id in getFields(schema):
+            if not hasattr(cls, f_id):
+                setattr(cls, f_id, FieldProperty(schema[f_id]))
+
+        cls.__id__ = unicode(name)
+        cls.__title__ = title
+        cls.__description__ = description
+        cls.__schema__ = DataProperty(schema)

Modified: z3ext.skintool/trunk/src/z3ext/skintool/subscribers.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/subscribers.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/subscribers.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -35,7 +35,7 @@
 
     if INoSkinSwitching.providedBy(event.request):
         return
-    
+
     site = removeAllProxies(site)
 
     if not ISkinable.providedBy(site):

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/__init__.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/__init__.py	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/__init__.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1 @@
+# This file is necessary to make this directory a package.

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/configure.zcml
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/configure.zcml	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/configure.zcml	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,19 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:z3ext="http://namespaces.zope.org/z3ext"
+   i18n_domain="zope">
+
+  <interface
+     name="DefaultSkin"
+     interface=".tests.IDefaultSkin"
+     type="zope.publisher.interfaces.browser.IBrowserSkinType" />
+
+  <!-- skintool -->
+  <z3ext:skin
+     name="Test Skin"
+     layer=".tests.ITestSkin"
+     title="test theme"
+     description="Test theme"
+     schema=".interfaces.ITestSkinSchema" />
+
+</configure>

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/ftesting.zcml
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/ftesting.zcml	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/ftesting.zcml	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,51 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:z3ext="http://namespaces.zope.org/z3ext"
+   xmlns:browser="http://namespaces.zope.org/browser"
+   i18n_domain="zope">
+
+  <include package="z3ext.autoinclude" file="meta.zcml" />
+  <includeAllDependencies package="z3ext.skintool" extras="test" />
+
+  <include package="z3ext.skintool.tests" />
+  <includeOverrides package="z3ext.skintool.tests" file="overrides.zcml" />
+
+ <browser:defaultSkin name="DefaultSkin" />
+
+  <securityPolicy component="z3ext.security.securitypolicy.SecurityPolicy" />
+
+  <role id="zope.Anonymous" title="Everybody" />
+  <role id="zope.Manager" title="Site Manager" />
+
+  <!-- Replace the following directive if you don't want public access -->
+  <grant permission="zope.View" role="zope.Anonymous" />
+
+  <!-- Principals -->
+  <unauthenticatedPrincipal
+      id="zope.anybody"
+      title="Unauthenticated User" />
+
+  <!-- Principal that tests generally run as -->
+  <principal
+      id="zope.mgr"
+      title="Manager"
+      login="mgr"
+      password="mgrpw" />
+
+  <principal
+      id="zope.user"
+      title="User"
+      login="user"
+      password="userpw" />
+
+  <principal
+      id="zope.user2"
+      title="User2"
+      login="user2"
+      password="userpw" />
+
+  <grant role="zope.Manager" principal="zope.mgr" />
+
+  <grantAll role="zope.Manager" />
+
+</configure>

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/interfaces.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/interfaces.py	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/interfaces.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,64 @@
+##############################################################################
+#
+# Copyright (c) 2008 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""
+
+$Id:  2007-12-12 12:27:02Z fafhrd $
+"""
+from zope import interface, schema
+
+
+class ITestSkinSchema(interface.Interface):
+
+    param1 = schema.TextLine(
+        title = u'Param 1',
+        default = u'1',
+        required = False)
+
+
+class ICategory(interface.Interface):
+
+    category = schema.TextLine(
+        title = u'Category',
+        required = False)
+
+
+class IPrefs1(interface.Interface):
+
+    name = schema.TextLine(
+        title = u'Name',
+        required = True)
+
+
+class IPrefs2(interface.Interface):
+
+    location = schema.TextLine(
+        title = u'Location',
+        default = u'',
+        required = False)
+
+
+class IPrefs3(interface.Interface):
+
+    location = schema.TextLine(
+        title = u'Location',
+        default = u'',
+        required = False)
+
+
+class IPrefs4(interface.Interface):
+
+    prefs4 = schema.TextLine(
+        title = u'Prefs4',
+        default = u'',
+        required = False)

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/overrides.zcml
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/overrides.zcml	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/overrides.zcml	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,12 @@
+<configure
+   xmlns="http://namespaces.zope.org/zope"
+   xmlns:z3ext="http://namespaces.zope.org/z3ext"
+   i18n_domain="zope">
+
+  <z3ext:layout
+     name="portal"
+     title="Test layout"
+     for="zope.app.component.interfaces.ISite"
+     template="testlayout.pt" />
+
+</configure>

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/testbrowser.txt
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/testbrowser.txt	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/testbrowser.txt	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,49 @@
+====================
+Personal preferences
+====================
+
+  >>> from zope import component, interface, event
+  >>> from zope.app.component.hooks import setSite
+
+  >>> from z3ext.skintool.interfaces import ISkinTool
+
+  >>> root = getRootFolder()
+  >>> setSite(root)
+
+  >>> configlet = component.getUtility(ISkinTool)
+  >>> configlet.skinData
+
+We have no data cause we haven't defined schema
+
+  >>> configlet.skin
+
+  >>> configlet.skin = 'Test Skin'
+
+  >>> configlet.skinData
+  <z3ext.skintool.skindatatype.SkinData<ui.portalskin.skindata> ...
+
+  >>> configlet.skinData.param1
+  u'1'
+
+Browser
+
+  >>> from zope.testbrowser.testing import Browser
+
+  >>> admin = Browser()
+  >>> admin.handleErrors = False
+  >>> admin.addHeader("Authorization", "Basic mgr:mgrpw")
+
+  >>> admin.open("http://localhost/settings/")
+  >>> admin.getLink('Portal skin').click()
+
+  >>> admin.getControl('Param 1').value
+  '1'
+  >>> admin.getControl('Param 1').value = 'Nikolay'
+  >>> admin.getControl(name="form.buttons.save").click()
+  >>> 'Data successfully updated.' in admin.contents
+  True
+
+We see changes in tool
+
+  >>> configlet.skinData.param1
+  u'Nikolay'

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/testlayout.pt
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/testlayout.pt	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/testlayout.pt	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,7 @@
+<html>
+  <body>
+    <div tal:content="structure provider:statusMessage"></div>
+
+    <div tal:content="structure view/render"></div>
+  </body>
+</html>

Added: z3ext.skintool/trunk/src/z3ext/skintool/tests/tests.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests/tests.py	                        (rev 0)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests/tests.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -0,0 +1,104 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Tests for the Preferences System
+
+$Id: tests.py 101560M 2009-07-05 07:54:33Z (local) $
+"""
+import os.path, unittest, doctest
+
+from zope import component
+from zope.component import testing
+from zope.testing import doctestunit
+from zope.app.testing import setup, functional
+from zope.app.intid.interfaces import IIntIds
+from zope.app.intid import IntIds
+from zope.app.rotterdam import Rotterdam
+
+from z3ext.controlpanel.testing import setUpControlPanel
+from z3ext.layoutform.interfaces import ILayoutFormLayer
+from z3ext.skintool.tool import SkinTool
+
+
+class IDefaultSkin(ILayoutFormLayer, Rotterdam):
+    """ skin """
+
+
+class ITestSkin(IDefaultSkin):
+    """ test Skin """
+
+
+z3extSkinTool = functional.ZCMLLayer(
+    os.path.join(os.path.split(__file__)[0], 'ftesting.zcml'),
+    __name__, 'z3extSkinTool', allow_teardown=True)
+
+
+def FunctionalDocFileSuite(*paths, **kw):
+    globs = kw.setdefault('globs', {})
+    globs['sync'] = functional.sync
+    globs['http'] = functional.HTTPCaller()
+    globs['getRootFolder'] = functional.getRootFolder
+
+    kw['package'] = doctest._normalize_module(kw.get('package'))
+
+    kwsetUp = kw.get('setUp')
+    def setUp(test):
+        functional.FunctionalTestSetup().setUp()
+
+        root = functional.getRootFolder()
+        root['intid'] = IntIds()
+        component.provideUtility(root['intid'], IIntIds)
+
+    kw['setUp'] = setUp
+
+    kwtearDown = kw.get('tearDown')
+    def tearDown(test):
+        functional.FunctionalTestSetup().tearDown()
+
+    kw['tearDown'] = tearDown
+
+    if 'optionflags' not in kw:
+        old = doctest.set_unittest_reportflags(0)
+        doctest.set_unittest_reportflags(old)
+        kw['optionflags'] = (old
+                             | doctest.ELLIPSIS
+                             | doctest.NORMALIZE_WHITESPACE)
+
+    suite = doctest.DocFileSuite(*paths, **kw)
+    suite.layer = z3extSkinTool
+    return suite
+
+def setUp(test):
+    site = setup.placefulSetUp(site=True)
+    setup.setUpTestAsModule(test, 'z3ext.skintool.README')
+    site['intid'] = IntIds()
+    component.provideUtility(site['intid'], IIntIds)
+    setUpControlPanel()
+    # register utility
+
+
+def tearDown(test):
+    setup.placefulTearDown()
+    setup.tearDownTestAsModule(test)
+
+def test_suite():
+    testbrowser = FunctionalDocFileSuite("testbrowser.txt")
+
+    return unittest.TestSuite((
+            testbrowser,
+            doctest.DocFileSuite(
+                '../README.txt',
+                setUp=setUp, tearDown=tearDown,
+                globs={'pprint': doctestunit.pprint},
+                optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS),
+            ))

Deleted: z3ext.skintool/trunk/src/z3ext/skintool/tests.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tests.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tests.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -1,51 +0,0 @@
-##############################################################################
-#
-# Copyright (c) 2008 Zope Corporation and Contributors.
-# All Rights Reserved.
-#
-# This software is subject to the provisions of the Zope Public License,
-# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
-# THIS SOFTWARE IS PROVIDED 'AS IS' AND ANY AND ALL EXPRESS OR IMPLIED
-# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
-# FOR A PARTICULAR PURPOSE.
-#
-##############################################################################
-""" 
-
-$Id$
-"""
-import unittest, doctest
-from zope import interface, component
-from zope.app.intid import IntIds
-from zope.app.intid.interfaces import IIntIds
-from zope.app.testing import setup
-
-from tool import SkinTool
-
-
-def setUp(test):
-    site = setup.placefulSetUp(site=True)
-    setup.setUpTestAsModule(test, 'z3ext.skintool.README')
-
-    site['intid'] = IntIds()
-    component.provideUtility(site['intid'], IIntIds)
-
-    # register utility
-    tool = SkinTool()
-    component.provideUtility(tool)
-
-
-def tearDown(test):
-    setup.placefulTearDown()
-    setup.tearDownTestAsModule(test)
-
-
-def test_suite():
-    return unittest.TestSuite((
-            doctest.DocFileSuite(
-                'README.txt',
-                setUp=setUp, tearDown=tearDown,
-                optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS,
-                ),
-            ))

Modified: z3ext.skintool/trunk/src/z3ext/skintool/tool.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/tool.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/tool.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -24,6 +24,7 @@
      IDefaultSkin, IBrowserRequest, IDefaultBrowserLayer
 from zope.app.component.hooks import getSite
 from zope.app.intid.interfaces import IIntIds
+from z3ext.layoutform import Fields, PageletEditSubForm
 
 from interfaces import IDefaultLayer, IDefaultLayers, ISkinTool
 
@@ -83,7 +84,18 @@
         bases.reverse()
         return bases
 
+    @property
+    def skinData(self):
+        skin = skins_byname.get(self.skin)
+        if skin:
+            data = self.data.get('skinData')
+            if data is None:
+                data = skins_registry[skin][-1]()
+                self.data['skinData'] = data
+            return data
+        return None
 
+
 @component.adapter(ISkinTool, IObjectModifiedEvent)
 def skinToolModified(*args):
     global cache
@@ -91,3 +103,19 @@
     id = getUtility(IIntIds).queryId(getSite())
     if id in cache:
         del cache[id]
+
+
+class SchemaEditForm(PageletEditSubForm):
+
+    @property
+    def fields(self):
+        data = self.getContent()
+        if data is not None:
+            return Fields(data.__schema__)
+        return Fields(interface.Interface)
+
+    def getContent(self):
+        return removeSecurityProxy(self.context).skinData
+
+    def isAvailable(self):
+        return len(self.fields)

Modified: z3ext.skintool/trunk/src/z3ext/skintool/zcml.py
===================================================================
--- z3ext.skintool/trunk/src/z3ext/skintool/zcml.py	2009-07-15 21:34:01 UTC (rev 101938)
+++ z3ext.skintool/trunk/src/z3ext/skintool/zcml.py	2009-07-15 22:16:15 UTC (rev 101939)
@@ -18,81 +18,93 @@
 from zope import schema, interface, component
 from zope.configuration.fields import Tokens, GlobalInterface, PythonIdentifier
 
+from skindatatype import SkinDataType
+
 from z3ext.skintool import tool
 
 
 class ISkinDirective(interface.Interface):
 
     layer = GlobalInterface(
-	title = u'Skin',
-        description = u'Skin interface.',
-	required = True)
+                title = u'Skin',
+                description = u'Skin interface.',
+                required = True)
 
     name = PythonIdentifier(
-	title = u'Name',
-	description = u'Content name.',
-	required = True)
+                title = u'Name',
+                description = u'Content name.',
+                required = True)
 
     title = schema.TextLine(
-	title = u'Title',
-	description = u'Content title.',
-	required = True)
+                title = u'Title',
+                description = u'Content title.',
+                required = True)
 
     description = schema.TextLine(
-	title = u'Description',
-	description = u'Content description.',
-	required = False)
+                title = u'Description',
+                description = u'Content description.',
+                required = False)
 
     require = Tokens(
-        title = u'Require',
-        description = u'Interface of layers that are '\
-            u'required by this layer.',
-        required = False,
-        value_type = GlobalInterface())
+                title = u'Require',
+                description = u'Interface of layers that are '\
+                    u'required by this layer.',
+                required = False,
+                value_type = GlobalInterface())
 
+    schema = GlobalInterface(
+                title = u'Schema',
+                description = u'Skin schema interface.',
+                default = interface.Interface)
 
+
 class ILayerDirective(interface.Interface):
 
     layer = GlobalInterface(
-	title = u'Layer',
-        description = u'Skin layer.',
-	required = True)
+                title = u'Layer',
+                description = u'Skin layer.',
+                required = True)
 
     name = PythonIdentifier(
-	title = u'Name',
-	description = u'Content name.',
-	required = True)
+                title = u'Name',
+                description = u'Content name.',
+                required = True)
 
     title = schema.TextLine(
-	title = u'Title',
-	description = u'Content title.',
-	required = True)
+                title = u'Title',
+                description = u'Content title.',
+                required = True)
 
     description = schema.TextLine(
-	title = u'Description',
-	description = u'Content description.',
-	required = False)
+                title = u'Description',
+                description = u'Content description.',
+                required = False)
 
 
-def skinDirectiveHandler(_context, layer, name, title, description='', require=[]):
+def skinDirectiveHandler(_context, layer, name, title, 
+                         description='',require=[],schema=interface.Interface):
     _context.action(
-	discriminator = ('z3ext.skintool-skin', layer, name),
-	callable = skinDirective,
-	args = (layer, name, title, description, require))
+        discriminator = ('z3ext.skintool-skin', layer, name),
+        callable = skinDirective,
+        args = (layer, name, title, description, require, schema))
 
 
-def skinDirective(layer, name, title, description, require):
+def skinDirective(layer, name, title, description, 
+                  require, schema=interface.Interface):
     sitemanager = component.getGlobalSiteManager()
 
     tool.skins_byname[name] = layer
-    tool.skins_registry[layer] = (layer, name, title, description, require)
+    skinDataClass = SkinDataType('ui.portalskin.skindata', schema)
+    interface.classImplements(skinDataClass, schema)
+    tool.skins_registry[layer] = (layer, name, title, 
+                                  description, require, skinDataClass)
 
 
 def layerDirectiveHandler(_context, layer, name, title, description=''):
     _context.action(
-	discriminator = ('z3ext.skintool-layer', layer, name),
-	callable = layerDirective,
-	args = (layer, name, title, description))
+        discriminator = ('z3ext.skintool-layer', layer, name),
+        callable = layerDirective,
+        args = (layer, name, title, description))
 
 
 def layerDirective(layer, name, title, description):



More information about the Checkins mailing list