[Checkins] SVN: grok/branches/darrylcousins-branch/ Added z3c template and layout views. Tests added for mars.macro

Darryl Cousins darryl at darrylcousins.net.nz
Wed Jul 4 21:18:51 EDT 2007


Log message for revision 77442:
  Added z3c template and layout views. Tests added for mars.macro

Changed:
  U   grok/branches/darrylcousins-branch/buildout.cfg
  U   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/README.txt
  U   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/meta.py
  U   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/directive.py
  U   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/ftesting.zcml
  A   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/macro.py
  A   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/
  A   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/first.pt
  A   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/navigation.pt
  U   grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/test_all.py
  U   grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/directive.py
  U   grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/ftesting.zcml
  U   grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/minimal-ftesting.zcml
  A   grok/branches/darrylcousins-branch/mars.view/
  A   grok/branches/darrylcousins-branch/mars.view/setup.py
  A   grok/branches/darrylcousins-branch/mars.view/src/
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/__init__.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/README.txt
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/__init__.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/components.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.txt
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/interfaces.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.zcml
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/__init__.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/directive.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/ftesting.zcml
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/layout.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/template.py
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/layout.pt
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/template.pt
  A   grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/test_all.py
  U   grok/branches/darrylcousins-branch/src/grok/util.py

-=-
Modified: grok/branches/darrylcousins-branch/buildout.cfg
===================================================================
--- grok/branches/darrylcousins-branch/buildout.cfg	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/buildout.cfg	2007-07-05 01:18:50 UTC (rev 77442)
@@ -1,5 +1,5 @@
 [buildout]
-develop = . mars.layer mars.template mars.macro
+develop = . mars.layer mars.template mars.macro mars.view
 parts = app data instance test
 find-links = http://download.zope.org/distribution/
 
@@ -13,6 +13,7 @@
        mars.layer
        mars.template
        mars.macro
+       mars.view
 recipe = zc.zope3recipes:app
 site.zcml = <include package="zope.security" file="meta.zcml" />
             <include package="zope.i18n" file="meta.zcml" />
@@ -91,5 +92,6 @@
        mars.layer
        mars.template
        mars.macro
+       mars.view
 defaults = ['--tests-pattern', '^f?tests$', '-v']
 

Modified: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/README.txt
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/README.txt	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/README.txt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -16,8 +16,16 @@
 
 ::
 
-    Code
+ class Navigation(mars.macro.MacroFactory):
+     """Name defaults to factory.__name__, 'navigation'"""
+     grok.template('templates/navigation.pt') # required
+     grok.context(zope.interface.Interface) # required if no module context 
 
+The following tal statement will look up the defined macro and insert its
+template.::
+
+ <div metal:use-macro="macro:naviagition" />
+
 Directives
 ----------
 

Modified: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/meta.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/meta.py	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/meta.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -7,6 +7,7 @@
 from zope.pagetemplate.interfaces import IPageTemplate
 
 from z3c.macro.zcml import MacroFactory
+from z3c.macro.interfaces import IMacroTemplate
 
 import martian
 from martian import util
@@ -54,7 +55,8 @@
         view = util.class_annotation(factory, 'mars.macro.view', IBrowserView)
 
         factory = MacroFactory(filepath, macro, contentType)
-        #print '\nname:', view_name,'context:', view_context,'factory:', factory, '\n'
+        #print '\nname:', view_name,'context:', view_context,\
+        #      'factory:', factory, 'view: ', view, 'layer', view_layer, '\n'
         zope.component.provideAdapter(factory,
                                  adapts=(view_context, view, view_layer),
                                  provides=IMacroTemplate,

Modified: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/directive.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/directive.py	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/directive.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -4,12 +4,65 @@
   >>> import grok
   >>> grok.grok('mars.macro.tests.directive')
 
+  >>> from mars.macro.tests.directive import Mammoth
+  >>> mammoth = getRootFolder()["mammoth"] = Mammoth()
+
   >>> from zope.testbrowser.testing import Browser
   >>> browser = Browser()
-  >>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+  >>> browser.handleErrors = False
+  >>> #browser.addHeader('Authorization', 'Basic mgr:mgrpw')
 
+  >>> browser.open('http://localhost/mammoth/@@first')
+  >>> print browser.contents
+  <html>
+    <body>
+      <h1>First Page</h1>
+      <div class="navi">
+  <BLANKLINE>
+  <BLANKLINE>
+     <div>My Navigation</div>
+  <BLANKLINE>
+  <BLANKLINE>
+      </div>
+      <div class="content">
+        Content here
+      </div>
+    </body>
+  </html>
+  <BLANKLINE>
+
 """
 
+import zope.component
+import zope.interface
+
+from z3c.template.interfaces import ILayoutTemplate
+
 import grok
 import mars.macro
+import mars.template
 
+class Mammoth(grok.Model):
+    pass
+
+class First(grok.View):
+
+    def __call__(self):
+        template = zope.component.getMultiAdapter(
+            (self, self.request), ILayoutTemplate)
+        return template(self)
+
+    def render(self):
+        pass
+
+class FirstLayout(mars.template.LayoutFactory):
+    grok.template('templates/first.pt')
+    grok.context(First)
+
+class MyNavigationMacro(mars.macro.MacroFactory):
+    grok.name('navigation') # define the name for macro
+    grok.template('templates/navigation.pt') # required
+    grok.context(Mammoth) # explicitly define the context
+    mars.macro.view(First) # explicitly define the view
+    mars.macro.content_type('text/html') # explicitly define content type
+

Modified: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/ftesting.zcml
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/ftesting.zcml	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/ftesting.zcml	2007-07-05 01:18:50 UTC (rev 77442)
@@ -11,6 +11,7 @@
 
   <include package="z3c.layer.minimal.tests" file="ftesting.zcml" />
 
+  <include package="z3c.macro" />
   <include package="grok" />
 
 </configure>

Added: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/macro.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/macro.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/macro.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,64 @@
+"""
+  >>> import grok
+  >>> grok.grok('mars.macro.tests.macro')
+
+  >>> from mars.macro.tests.macro import Mammoth
+  >>> mammoth = getRootFolder()["mammoth"] = Mammoth()
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+  >>> #browser.addHeader('Authorization', 'Basic mgr:mgrpw')
+
+  >>> browser.open('http://localhost/mammoth/@@first')
+  >>> print browser.contents
+  <html>
+    <body>
+      <h1>First Page</h1>
+      <div class="navi">
+  <BLANKLINE>
+  <BLANKLINE>
+     <div>My Navigation</div>
+  <BLANKLINE>
+  <BLANKLINE>
+      </div>
+      <div class="content">
+        Content here
+      </div>
+    </body>
+  </html>
+  <BLANKLINE>
+
+"""
+
+import zope.component
+import zope.interface
+
+from z3c.template.interfaces import ILayoutTemplate
+
+import grok
+import mars.macro
+import mars.template
+
+class Navigation(mars.macro.MacroFactory):
+    """Name defaults to factory.__name__, 'navigation'"""
+    grok.template('templates/navigation.pt') # required
+    grok.context(zope.interface.Interface) # required if no module context 
+
+class Mammoth(grok.Model):
+    pass
+
+class First(grok.View):
+
+    def __call__(self):
+        template = zope.component.getMultiAdapter(
+            (self, self.request), ILayoutTemplate)
+        return template(self)
+
+    def render(self):
+        pass
+
+class FirstLayout(mars.template.LayoutFactory):
+    grok.template('templates/first.pt')
+    grok.context(First)
+


Property changes on: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/macro.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/first.pt
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/first.pt	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/first.pt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,13 @@
+<html>
+  <body>
+    <h1>First Page</h1>
+    <div class="navi">
+      <tal:block define="title string:My Navigation">
+        <metal:block use-macro="macro:navigation" />
+      </tal:block>
+    </div>
+    <div class="content">
+      Content here
+    </div>
+  </body>
+</html>

Added: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/navigation.pt
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/navigation.pt	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/templates/navigation.pt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,3 @@
+<metal:block define-macro="navigation">
+   <div tal:content="title">---</div>
+</metal:block>

Modified: grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/test_all.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/test_all.py	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.macro/src/mars/macro/tests/test_all.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -9,7 +9,7 @@
 def test_suite():
     suite = unittest.TestSuite()
     dottedname = 'mars.macro.tests.%s'
-    for name in ['directive']:
+    for name in ['directive', 'macro']:
         test = FunctionalDocTestSuite(dottedname % name)
         test.layer = TestLayer
         suite.addTest(test)

Modified: grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/directive.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/directive.py	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/directive.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -14,8 +14,8 @@
   >>> browser = Browser()
   >>> browser.handleErrors = False
 
-  >>> #browser.open("http://localhost/++skin++myskin/mammoth/@@view")
-  >>> browser.open("http://localhost/mammoth/@@view")
+  >>> browser.open("http://localhost/++skin++myskin/mammoth/@@view")
+  >>> #browser.open("http://localhost/mammoth/@@view")
   >>> print browser.contents
   <body>
   <div>Rendered content</div>
@@ -35,6 +35,7 @@
 
 import mars.template
 import mars.layer
+import mars.view
 
 class IMyLayer(mars.layer.IMinimalLayer):
     pass
@@ -48,13 +49,12 @@
 class Mammoth(grok.Model):
     pass
 
-class View(grok.View):
+class View(mars.view.LayoutView):
+    """Here use LayoutView which uses layers"""
+    mars.layer.layer(IMyLayer)
+    mars.view.layout('complex') # forces named layout template lookup
+    _layout_interface = IMyPageTemplate # if template provides specific interface
 
-    def __call__(self):
-        template = zope.component.getMultiAdapter(
-            (self, self.request), IMyPageTemplate, name='complex')
-        return template(self)
-
     def render(self):
         return u'Rendered content'
 
@@ -65,6 +65,6 @@
     grok.provides(IMyPageTemplate) # view must use this interface to lookup
     mars.template.macro('body') # define the macro to use
     mars.template.content_type('text/html') # define the contentType
-    #mars.layer.layer(IMyLayer) # registered on this layer.
+    mars.layer.layer(IMyLayer) # registered on this layer.
     
 

Modified: grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/ftesting.zcml
===================================================================
--- grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/ftesting.zcml	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/ftesting.zcml	2007-07-05 01:18:50 UTC (rev 77442)
@@ -7,7 +7,7 @@
   <include package="grok" file="meta.zcml" />
   <include package="mars.template" file="meta.zcml" />
   <include package="mars.layer" file="meta.zcml" />
-  <include package="zope.app.pagetemplate" file="meta.zcml" />
+  <include package="mars.view" file="meta.zcml" />
 
   <include package="zope.app.zcmlfiles" />
 

Modified: grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/minimal-ftesting.zcml
===================================================================
--- grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/minimal-ftesting.zcml	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/mars.template/src/mars/template/tests/minimal-ftesting.zcml	2007-07-05 01:18:50 UTC (rev 77442)
@@ -7,6 +7,7 @@
   <include package="grok" file="meta.zcml" />
   <include package="mars.template" file="meta.zcml" />
   <include package="mars.layer" file="meta.zcml" />
+  <include package="mars.view" file="meta.zcml" />
 
   <include package="z3c.layer.minimal.tests" file="ftesting.zcml" />
 

Added: grok/branches/darrylcousins-branch/mars.view/setup.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/setup.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/setup.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,33 @@
+import os
+from setuptools import setup, find_packages
+
+def read(*rnames):
+    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
+
+setup(
+    name='mars.view',
+    version='0.1',
+    author='Darryl Cousins',
+    author_email='darryl.cousins at tfws.org.nz',
+    url='http://www.tfws.org.nz/martian',
+    description="""\
+Martian is a library that allows the embedding of configuration
+information in Python code. Martian can then grok the system and
+do the appropriate configuration registrations.
+
+This package uses martian to define views""",
+    long_description=(
+        read('src/mars/view/README.txt')
+        ),
+    packages=find_packages('src'),
+    package_dir = {'': 'src'},
+    include_package_data = True,
+    zip_safe=False,
+    license='ZPL',
+    install_requires=['setuptools',
+                      'martian',
+                      'grok',
+                     ],
+)
+
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/setup.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/__init__.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/__init__.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/__init__.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,7 @@
+try:
+    # Declare this a namespace package if pkg_resources is available.
+    import pkg_resources
+    pkg_resources.declare_namespace('mars')
+except ImportError:
+    pass
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/README.txt
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/README.txt	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/README.txt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,41 @@
+=========
+Mars View
+=========
+
+Martian is a library that allows the embedding of configuration
+information in Python code. Martian can then grok the system and
+do the appropriate configuration registrations.
+
+z3c packages bring significant clarity and a pattern for forms, view and
+templates.
+
+This package uses martian to configure views. The views here defined are
+TemplateView and LayoutView, both use adapter lookup to locate the template to
+be used (but can class attributes `template` for TemplateView and LayoutView and `layout` for
+LayoutView will be used before adapter lookup).
+
+TemplateView provides only a `render` method which returns the rendered
+template.
+
+LayoutView has a `__call__` method that returns the rendered layout template in
+addition to a `render` method inherited from TemplateView which returns the
+rendered template.
+
+Example Code
+------------
+
+::
+
+    Code
+
+Directives
+----------
+
+Please see ``directive.txt``.
+
+Tests
+-----
+
+See test directory.
+
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/README.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/__init__.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/__init__.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/__init__.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,3 @@
+from directive import layout
+from components import TemplateView, LayoutView
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/components.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/components.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/components.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,124 @@
+import zope.component
+import zope.interface
+from zope.component.interfaces import ComponentLookupError
+from zope.publisher.browser import BrowserPage
+from zope.publisher.publish import mapply
+from zope.pagetemplate.interfaces import IPageTemplate
+
+from z3c.template.interfaces import ILayoutTemplate
+
+import grok
+from grok.interfaces import IGrokView
+
+class ViewBase(object):
+
+    template_name = u''
+
+    def application(self):
+        obj = self.context
+        while obj is not None:
+            if isinstance(obj, grok.Application):
+                return obj
+            obj = obj.__parent__
+        raise ValueErrror("No application found.")
+
+    def site(self):
+        obj = self.context
+        while obj is not None:
+            if isinstance(obj, grok.Site):
+                return obj
+            obj = obj.__parent__
+        raise ValueErrror("No site found.")
+
+    def application_url(self, name=None):
+        obj = self.context
+        while obj is not None:
+            if isinstance(obj, grok.Application):
+                return self.url(obj, name)
+            obj = obj.__parent__
+        raise ValueErrror("No application found.")
+
+    def url(self, obj=None, name=None):
+        # if the first argument is a string, that's the name. There should
+        # be no second argument
+        if isinstance(obj, basestring):
+            if name is not None:
+                raise TypeError(
+                    'url() takes either obj argument, obj, string arguments, '
+                    'or string argument')
+            name = obj
+            obj = None
+
+        if name is None and obj is None:
+            # create URL to view itself
+            obj = self
+        elif name is not None and obj is None:
+            # create URL to view on context
+            obj = self.context
+        return url(self.request, obj, name)
+        
+    def redirect(self, url):
+        return self.request.response.redirect(url)
+        
+    @property
+    def response(self):
+        return self.request.response
+
+    def update(self):
+        pass
+
+    def __getitem__(self, key):
+        # give nice error message if template is None
+        return self.template.macros[key]
+
+class TemplateViewBase(BrowserPage, ViewBase):
+    """Mixin to reuse render method"""
+    template = None
+    _template_name = u'' # will be set if grok.template defined
+    _template_interface = IPageTemplate
+
+    def render(self):
+        mapply(self.update, (), self.request)
+        if self.request.response.getStatus() in (302, 303):
+            return
+        template = getattr(self, 'template', None)
+        if template is None:
+            template = zope.component.getMultiAdapter(
+                (self, self.request), self._template_interface, 
+                name=self._template_name)
+            return template(self)
+        return template(self)
+
+class TemplateView(TemplateViewBase):
+    """This differs from the above in that instead of expecting a template
+    or render method, the template will be looked up.
+    No call method is provided.
+    """
+
+    def __init__(self, context, request):
+        super(TemplateView, self).__init__(context, request)
+
+class LayoutView(TemplateViewBase):
+    """This differs from the above in that instead of expecting a template
+    or render method, a layout template will be looked up in the call method
+    """
+    layout = None
+    _layout_name = u'' # will be set if mars.view.layout defined
+    _layout_interface = ILayoutTemplate
+
+
+    def __init__(self, context, request):
+        super(LayoutView, self).__init__(context, request)
+
+    def __call__(self):
+        mapply(self.update, (), self.request)
+        if self.request.response.getStatus() in (302, 303):
+            return
+        layout = getattr(self, 'layout', None)
+        if layout is None:
+            layout = zope.component.getMultiAdapter(
+                    (self, self.request), self._layout_interface, 
+                    name=self._layout_name)
+            return layout(self)
+        return layout(self)
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/components.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,4 @@
+from martian.directive import (SingleTextDirective,
+                               ClassDirectiveContext)
+
+layout = SingleTextDirective('mars.view.layout', ClassDirectiveContext())


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.txt
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.txt	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.txt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,41 @@
+========================
+Mars Template Directives
+========================
+
+Directives specific to this package
+-----------------------------------
+
+* mars.view.layout(name):
+  If defined the layout for LayoutView will be looked up as a `named adapter`.
+  Should only be defined if the layout template has been registered as a named
+  adapter.
+  Default: ''
+
+
+The mars.layer directive may be used
+-----------------------------------------
+
+* mars.layer.layer(class_or_interface):
+  The layer for which the template should be available.
+  Default: zope.publisher.browser.interfaces.IDefaultBrowserLayer
+
+Relevant grok directives
+------------------------
+
+* grok.name(name):
+  Name of the view, available in url as object/@@viewname.
+  Default: factory.__name__.lower()
+
+* grok.context(class_or_interface):
+  The view for which the template should be available. Usually should be
+  defined.
+  Default: module context
+
+* grok.template(name):
+  If defined the template will be looked up as a `named adapter`. Should only be
+  defined if the template has been registered as a named adapter.
+  Default: ''
+
+* grok.provides(class_or_interface):
+  Interface the class is looked up as, probably wouldn't be used.
+  Default: zope.interface.Interface


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/directive.txt
___________________________________________________________________
Name: svn:keywords
   + Date Author

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/interfaces.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/interfaces.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/interfaces.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,11 @@
+import zope.interface
+
+class IMarsViewDirectives(zope.interface.Interface):
+
+    def layout(name):
+        """Declare the layout name for a view.
+        If defined the layout will be looked up as a named adapter.
+        Should only be defined if the layout template has been registered as a named
+        adapter.
+        """
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/interfaces.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,96 @@
+import zope.component
+import zope.interface
+from zope.publisher.interfaces.browser import IDefaultBrowserLayer
+
+from z3c.template.template import TemplateFactory
+
+import martian
+from martian.error import GrokError
+from martian import util
+
+import grok
+from grok.util import get_default_permission, make_checker
+
+import mars.view
+
+class ViewGrokkerBase(martian.ClassGrokker):
+    """Code resuse for View, ContentProvider and Viewlet grokkers"""
+    component_class = None
+    factory_name = ''
+    view_name = ''
+    layer_name = ''
+    view_context = None
+    provider = zope.interface.Interface
+
+    def grok(self, name, factory, context, module_info, templates):
+        self.view_context = util.determine_class_context(factory, context)
+        factory.module_info = module_info
+        self.factory_name = factory.__name__.lower()
+
+        self.view_layer = util.class_annotation(factory, 'mars.layer.layer',
+                                           None) or module_info.getAnnotation('mars.layer.layer',
+                                               None) or IDefaultBrowserLayer
+
+        self.view_name = util.class_annotation(factory, 'grok.name',
+                                          self.factory_name)
+
+        # is name defined for template?
+        # if defined a named template is looked up
+        factory._template_name = util.class_annotation(factory, 'grok.template', '')
+
+        # __view_name__ is needed to support IAbsoluteURL on views
+        # TODO check how this is working for these views
+        factory.__view_name__ = self.view_name
+
+        # don't know if this would ever need to be set
+        self.provides = util.class_annotation(factory, 'grok.provides',
+                                                self.provider)
+        #print '\nname:', self.view_name,'context:', self.view_context,'factory:', factory,\
+        #      'layer:', self.view_layer, '\n'
+        self.register(factory, module_info)
+
+        # protect view, public by default
+        default_permission = get_default_permission(factory)
+        make_checker(factory, factory, default_permission)
+
+        # safety belt: make sure that the programmer didn't use
+        # @grok.require on any of the view's methods.
+        methods = util.methods_from_class(factory)
+        for method in methods:
+            if getattr(method, '__grok_require__', None) is not None:
+                raise GrokError('The @grok.require decorator is used for '
+                                'method %r in view %r. It may only be used '
+                                'for XML-RPC methods.'
+                                % (method.__name__, factory), factory)
+
+        return True
+
+    def register(self, factory, module_info):
+        """Must be defined in subclasses, module_info may be necessary for further lookups"""
+        pass
+
+
+class TemplateViewGrokker(ViewGrokkerBase):
+    component_class = mars.view.TemplateView
+
+    def register(self, factory, module_info):
+
+        zope.component.provideAdapter(factory,
+                                 adapts=(self.view_context, self.view_layer),
+                                 provides=self.provides,
+                                 name=self.view_name)
+
+class LayoutViewGrokker(ViewGrokkerBase):
+    component_class = mars.view.LayoutView
+
+    def register(self, factory, module_info):
+
+        # is name defined for layout?
+        # if defined a named template is looked up
+        factory._layout_name = util.class_annotation(factory, 'mars.view.layout', '')
+
+        zope.component.provideAdapter(factory,
+                                 adapts=(self.view_context, self.view_layer),
+                                 provides=self.provides,
+                                 name=self.view_name)
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.zcml
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.zcml	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/meta.zcml	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,2 @@
+<grok package=".meta" xmlns="http://namespaces.zope.org/grok" />
+

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/__init__.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/__init__.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/__init__.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1 @@
+#


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/__init__.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/directive.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/directive.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/directive.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,15 @@
+"""
+Test the claimed directives.
+
+  >>> import grok
+  >>> grok.grok('mars.view.tests.directive')
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+"""
+
+import grok
+import mars.view
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/directive.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/ftesting.zcml
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/ftesting.zcml	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/ftesting.zcml	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,18 @@
+<configure xmlns="http://namespaces.zope.org/zope"
+           xmlns:meta="http://namespaces.zope.org/meta"
+           xmlns:browser="http://namespaces.zope.org/browser"
+           i18n_domain="zope"
+           package="mars.template.tests">
+
+  <include package="grok" file="meta.zcml" />
+  <include package="mars.template" file="meta.zcml" />
+  <include package="mars.layer" file="meta.zcml" />
+  <include package="mars.view" file="meta.zcml" />
+
+  <include package="z3c.layer.minimal.tests" file="ftesting.zcml" />
+
+  <include package="grok" />
+
+</configure>
+
+

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/layout.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/layout.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/layout.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,118 @@
+"""
+Testing the LayoutView, which unlike grok.View will look up a layout.
+
+  >>> import grok
+  >>> from mars.view.tests.layout import Mammoth
+  >>> grok.grok('mars.view.tests.layout')
+  >>> getRootFolder()["manfred"] = Mammoth()
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+These tests make use of minimal layer
+
+  >>> skinURL = 'http://localhost/++skin++myskin'
+
+Since a layout template is not yet registered, calling the view will fail:
+
+  >>> browser.open("http://localhost/manfred/@@drawing")
+  Traceback (most recent call last):
+  ...
+  NotFound: ......
+
+  >>> browser.open(skinURL + "/manfred/@@drawing")
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ......
+
+We'll manually register a layout template.
+
+  >>> import os, tempfile
+  >>> temp_dir = tempfile.mkdtemp()
+  >>> layout = os.path.join(temp_dir, 'layout.pt')
+  >>> open(layout, 'w').write('''
+  ...   <div tal:content="view/render">
+  ...     Full layout
+  ...   </div>
+  ... ''')
+
+  >>> from z3c.template.interfaces import ILayoutTemplate
+  >>> from z3c.template.template import TemplateFactory
+  >>> from zope.publisher.interfaces.browser import IBrowserRequest
+  >>> import zope.component
+  >>> from mars.view.tests.layout import Drawing
+  >>> factory = TemplateFactory(layout, 'text/html')
+  >>> zope.component.provideAdapter(factory,
+  ...     (Drawing, IBrowserRequest), ILayoutTemplate)
+
+  >>> browser.open(skinURL + "/manfred/@@drawing")
+  >>> print browser.contents
+  <div>Rendered content</div>
+
+  >>> import shutil
+  >>> shutil.rmtree(temp_dir)
+
+We can also use mars.template to provide the layout template.
+
+  >>> browser.open(skinURL + "/manfred/@@view")
+  >>> print browser.contents
+  <div>View template</div>
+
+Both layout and template can be used with LayoutView, the template being
+rendered by LayoutView's `render` method.
+
+  >>> browser.open(skinURL + "/manfred/@@full")
+  >>> print browser.contents
+  <html>
+  <body><div>View template</div>
+  </body>
+  </html>
+  <BLANKLINE>
+
+
+"""
+import zope.interface
+
+import grok
+import mars.view
+import mars.template
+import mars.layer
+
+class IMyLayer(mars.layer.IMinimalLayer):
+    pass
+
+# set layer on module level, all class declarations that use directive
+# mars.layer.layer will use this layer - Skin, views and templates
+mars.layer.layer(IMyLayer)
+
+class MySkin(mars.layer.Skin):
+    pass
+
+class Mammoth(grok.Model):
+    pass
+
+class Drawing(mars.view.LayoutView):
+    pass
+
+    def render(self):
+        return u'Rendered content'
+
+class View(mars.view.LayoutView):
+    pass
+
+class ViewLayout(mars.template.LayoutFactory):
+    grok.template('templates/template.pt')
+    grok.context(View)
+
+class Full(mars.view.LayoutView):
+    pass
+
+class FullLayout(mars.template.LayoutFactory):
+    grok.template('templates/layout.pt')
+    grok.context(Full)
+
+class FullTemplate(mars.template.TemplateFactory):
+    grok.template('templates/template.pt')
+    grok.context(Full)
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/layout.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/template.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/template.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/template.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,74 @@
+"""
+Testing the TemplateView, which unlike grok.View will look up a template.
+
+  >>> import grok
+  >>> from mars.view.tests.template import Mammoth, Painting
+  >>> grok.grok('mars.view.tests.template')
+  >>> mammoth = getRootFolder()["manfred"] = Mammoth()
+
+  >>> from zope.testbrowser.testing import Browser
+  >>> browser = Browser()
+  >>> browser.handleErrors = False
+
+TemplateViews look up a template as an adpater.
+
+  >>> from zope.publisher.browser import TestRequest
+  >>> request = TestRequest()
+  >>> view = Painting(mammoth, request)
+
+Since a template is not yet registered, rendering the view will fail:
+
+  >>> print view.render()
+  Traceback (most recent call last):
+  ...
+  ComponentLookupError: ......
+
+We can register a template for the view.
+
+  >>> import os, tempfile
+  >>> temp_dir = tempfile.mkdtemp()
+  >>> from zope.pagetemplate.interfaces import IPageTemplate
+  >>> from z3c.template.template import TemplateFactory
+  >>> from zope.publisher.interfaces.browser import IBrowserRequest
+  >>> import zope.component
+  >>> template = os.path.join(temp_dir, 'template.pt')
+  >>> open(template, 'w').write('''
+  ...   <div>Rendered content</div>
+  ... ''')
+
+  >>> factory = TemplateFactory(template, 'text/html')
+  >>> zope.component.provideAdapter(factory,
+  ...     (Painting, IBrowserRequest), IPageTemplate)
+
+  >>> print view.render()
+  <div>Rendered content</div>
+
+  >>> import shutil
+  >>> shutil.rmtree(temp_dir)
+
+We can also use mars.template to provide the template.
+
+  >>> from mars.view.tests.template import View
+  >>> view = View(mammoth, request)
+  >>> print view.render()
+  <div>View template</div>
+
+"""
+import grok
+import mars.view
+import mars.template
+
+class Mammoth(grok.Model):
+    pass
+
+class Painting(mars.view.TemplateView):
+    pass
+
+class View(mars.view.TemplateView):
+    pass
+
+class ViewTemplate(mars.template.TemplateFactory):
+    grok.template('templates/template.pt')
+    grok.context(View)
+
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/template.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/layout.pt
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/layout.pt	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/layout.pt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,3 @@
+<html>
+<body tal:content="structure view/render" />
+</html>

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/template.pt
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/template.pt	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/templates/template.pt	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1 @@
+<div>View template</div>

Added: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/test_all.py
===================================================================
--- grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/test_all.py	                        (rev 0)
+++ grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/test_all.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -0,0 +1,22 @@
+import unittest
+from pkg_resources import resource_listdir
+
+from grok.ftests.test_grok_functional import FunctionalDocTestSuite
+
+from zope.app.testing import functional
+functional.defineLayer('TestLayer', 'ftesting.zcml')
+
+def test_suite():
+    suite = unittest.TestSuite()
+    dottedname = 'mars.view.tests.%s'
+    for name in ['layout']:
+        test = FunctionalDocTestSuite(dottedname % name)
+        test.layer = TestLayer
+        suite.addTest(test)
+
+    return suite
+
+
+if __name__ == '__main__':
+    unittest.main(defaultTest='test_suite')
+


Property changes on: grok/branches/darrylcousins-branch/mars.view/src/mars/view/tests/test_all.py
___________________________________________________________________
Name: svn:keywords
   + Id

Modified: grok/branches/darrylcousins-branch/src/grok/util.py
===================================================================
--- grok/branches/darrylcousins-branch/src/grok/util.py	2007-07-05 00:08:19 UTC (rev 77441)
+++ grok/branches/darrylcousins-branch/src/grok/util.py	2007-07-05 01:18:50 UTC (rev 77442)
@@ -44,6 +44,7 @@
         checker = NamesChecker(['__call__'])
     else:
         checker = NamesChecker(['__call__'], permission)
+
     defineChecker(view_factory, checker)
 
 def check_permission(factory, permission):



More information about the Checkins mailing list