[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