[Checkins] SVN: zope.browserzcml2/trunk/src/zope/browserzcml2/ Implement browser2:pagesFromClass directive

Philipp von Weitershausen philikon at philikon.de
Fri Apr 21 14:24:25 EDT 2006


Log message for revision 67248:
  Implement browser2:pagesFromClass directive
  

Changed:
  U   zope.browserzcml2/trunk/src/zope/browserzcml2/README.txt
  U   zope.browserzcml2/trunk/src/zope/browserzcml2/meta.zcml
  U   zope.browserzcml2/trunk/src/zope/browserzcml2/zcml.py

-=-
Modified: zope.browserzcml2/trunk/src/zope/browserzcml2/README.txt
===================================================================
--- zope.browserzcml2/trunk/src/zope/browserzcml2/README.txt	2006-04-21 18:14:08 UTC (rev 67247)
+++ zope.browserzcml2/trunk/src/zope/browserzcml2/README.txt	2006-04-21 18:24:24 UTC (rev 67248)
@@ -183,9 +183,46 @@
 Pages from classes
 ------------------
 
-XXX
+Sometimes, out of pure convenience, you'd like to define several pages
+in one class.  Each page would be implemented as a method or other
+callable attribute.  For example:
 
+  >>> class PhoenixPages(object):
+  ...     macgyver = ViewPageTemplateFile('test.pt')
+  ...     def pete(self):
+  ...         return u'Peter Thornton'
 
+These are configured in one large ZCML directive:
+
+  >>> run_config("""
+  ... <browser2:pagesFromClass
+  ...     for="*"
+  ...     class="zope.browserzcml2.README.PhoenixPages"
+  ...     >
+  ...     <page
+  ...         name="fromclass1.html"
+  ...         attribute="macgyver"
+  ...         permission="zope.Public"
+  ...         />
+  ...     <page
+  ...         name="fromclass2.html"
+  ...         attribute="pete"
+  ...         permission="zope.Public"
+  ...         />
+  ... </browser2:pagesFromClass>
+  ... """)
+
+As any other page, we can look them up and call them.  They *are*
+instances of a dynamically generated class, though:
+
+  >>> page = zope.component.getMultiAdapter((object(), request),
+  ...                                       name=u'fromclass1.html')
+  >>> page #doctest: +ELLIPSIS
+  <zope.browserzcml2.zcml.PageFromClass object at ...>
+  >>> page()
+  u"Hi, the name's MacGyver.\n"
+
+
 Conflicts
 ---------
 

Modified: zope.browserzcml2/trunk/src/zope/browserzcml2/meta.zcml
===================================================================
--- zope.browserzcml2/trunk/src/zope/browserzcml2/meta.zcml	2006-04-21 18:14:08 UTC (rev 67247)
+++ zope.browserzcml2/trunk/src/zope/browserzcml2/meta.zcml	2006-04-21 18:24:24 UTC (rev 67248)
@@ -16,6 +16,17 @@
         handler=".zcml.page"
         />
 
+    <meta:complexDirective
+        name="pagesFromClass"
+        schema=".zcml.IPagesFromClassDirective"
+        handler=".zcml.PagesFromClass"
+        >
+      <meta:subdirective
+          name="page"
+          schema=".zcml.IPageSubdirective"
+          />
+    </meta:complexDirective>
+
   </meta:directives>
 
 </configure>

Modified: zope.browserzcml2/trunk/src/zope/browserzcml2/zcml.py
===================================================================
--- zope.browserzcml2/trunk/src/zope/browserzcml2/zcml.py	2006-04-21 18:14:08 UTC (rev 67247)
+++ zope.browserzcml2/trunk/src/zope/browserzcml2/zcml.py	2006-04-21 18:24:24 UTC (rev 67248)
@@ -17,9 +17,10 @@
 """
 __docformat__ = "reStructuredText"
 
+import zope.interface
+import zope.formlib
 import zope.configuration.fields
 import zope.configuration.exceptions
-import zope.formlib
 import zope.i18nmessageid
 _ = zope.i18nmessageid.MessageFactory('zope')
 
@@ -31,6 +32,7 @@
 from zope.app.publisher.browser.viewmeta import _handle_menu
 from zope.app.pagetemplate import ViewPageTemplateFile
 from zope.app.component.metaconfigure import adapter
+from zope.app.security.fields import Permission
 
 class IPageDirective(IViewCharacteristics, IRegisterInMenu):
     """Define a browser page"""
@@ -85,14 +87,74 @@
          menu, title)
 
 
-class IPagesFromClassDirective(IViewCharacteristics):
+class IPagesFromClassDirective(zope.interface.Interface):
     """Define multiple pages from a single class"""
 
     class_ = zope.configuration.fields.GlobalObject(
         title=_(u"Class"),
         description=_(u"A class from which one or more browser pages will "
                       "be dynamically created and registered"),
+        required=True,
+        )
+
+    for_ = zope.configuration.fields.GlobalObject(
+        title=_(u'Registered for'),
+        description=_(u"The interface or class this view is for."),
+        required=True
+        )
+
+    layer = zope.configuration.fields.GlobalInterface(
+        title=_('Layer'),
+        description=_("""Layer that the view is registered for.
+        This defaults to IDefaultBrowserLayer."""),
         required=False,
         )
 
-# XXX PagesFromClass
+class IPageSubdirective(IRegisterInMenu):
+    """Define a page based on an attribute of a class"""
+
+    name = zope.schema.TextLine(
+        title=_(u'Name'),
+        description=_(u"""The name of a view, which will show up e.g. in
+        URLs and other paths."""),
+        required=True
+        )
+
+    permission = Permission(
+        title=_(u'Permission'),
+        description=_(u"The permission needed to use the view."),
+        required=True
+        )
+
+    attribute = zope.configuration.fields.PythonIdentifier(
+        title=_(u'Attribute'),
+        description=_(u"The name of the class attribute that will be called "
+                      "when the page is published the page."),
+        required=True
+        )
+
+class PagesFromClass(object):
+
+    def __init__(self, _context, class_, for_, layer=IDefaultBrowserLayer):
+        self._context = _context
+        self.class_ = class_
+        self.for_ = for_
+        self.layer = layer
+
+    def page(self, _context, name, permission, attribute,
+             menu=None, title=None):
+        if attribute == '__call__':
+            class PageFromClass(zope.formlib.Page, self.class_):
+                pass
+        else:
+            class PageFromClass(zope.formlib.Page, self.class_):
+                def __call__(self, *arg, **kw):
+                    return getattr(self, attribute)(*arg, **kw)
+
+        page(self._context, PageFromClass,
+             self.for_, name, permission, self.layer,
+             menu, title)
+
+    def __call__(self):
+        pass
+    



More information about the Checkins mailing list