[Checkins] SVN: megrok.layout/trunk/ Fix megrok.layout with new versions of grokcore.view
Souheil CHELFOUH
souheil at chelfouh.com
Mon Oct 18 05:58:37 EDT 2010
Log message for revision 117654:
Fix megrok.layout with new versions of grokcore.view
Changed:
D megrok.layout/trunk/README.txt
U megrok.layout/trunk/docs/HISTORY.txt
U megrok.layout/trunk/setup.py
U megrok.layout/trunk/src/megrok/layout/README.txt
U megrok.layout/trunk/src/megrok/layout/__init__.py
U megrok.layout/trunk/src/megrok/layout/components.py
U megrok.layout/trunk/src/megrok/layout/ftests/test_general.py
U megrok.layout/trunk/src/megrok/layout/ftests/test_layout.py
U megrok.layout/trunk/src/megrok/layout/ftests/test_layoutlayers.py
U megrok.layout/trunk/src/megrok/layout/ftests/test_page.py
U megrok.layout/trunk/src/megrok/layout/ftests/test_specializedlayout.py
U megrok.layout/trunk/src/megrok/layout/interfaces.py
U megrok.layout/trunk/src/megrok/layout/meta.py
U megrok.layout/trunk/src/megrok/layout/tests/test_norenderortemplatelayout.py
U megrok.layout/trunk/src/megrok/layout/tests/test_renderandtemplate.py
-=-
Deleted: megrok.layout/trunk/README.txt
===================================================================
--- megrok.layout/trunk/README.txt 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/README.txt 2010-10-18 09:58:36 UTC (rev 117654)
@@ -1,115 +0,0 @@
-=============
-megrok.layout
-=============
-
-The `megrok.layout` package provides a simple way to write view
-components which can be included into a defined layout. It turns
-around two main components : the Page and the Layout.
-
-
-Getting started
----------------
-
-First we grok this package's grokkers::
-
- >>> from megrok.layout import testing
- >>> import grokcore.component as grok
- >>> from grokcore.component.testing import grok_component
- >>> testing.grok('megrok.layout')
-
-
-
-Layout
-------
-
-The layout is a component allowing you to design your site. Often,
-it's the common structure shared between all the pages. Technically,
-it is a class based on the view components interface, providing a
-'render' and 'update' method.
-
-Let's implement a simple Layout:
-
- >>> from megrok.layout import Layout
- >>> from zope.interface import Interface
-
- >>> class MyLayout(Layout):
- ... grok.name('mylayout')
- ... grok.context(Interface)
- ...
- ... def render(self):
- ... return u"a simple layout"
-
-We grok our component:
-
- >>> grok_component('MyLayout', MyLayout)
- True
-
-We check it has been correctly registered:
-
- >>> from megrok.layout import ILayout
- >>> from zope.component import getMultiAdapter
- >>> from zope.publisher.browser import TestRequest
-
- >>> layout = getMultiAdapter((Interface, TestRequest()), ILayout)
- >>> isinstance(layout, MyLayout)
- True
- >>> layout.render()
- u'a simple layout'
-
-Now let's see how to use this Layout in a specific context using a Page.
-
-
-Page
-----
-
-The page is the specific code that you want to control. It is based on
-the grokcore.View browser page implementation and therefore provides a
-'render' and 'update' method. The 'render' method will simply return the
-specific HTML code generated by the template or the 'render' method
-code while '__call__' will lookup for a Layout component and renders
-itself inside it.
-
-First, we'll create 2 models that will serve as exemples.
-
- >>> class Aurochs(grok.Context):
- ... description = u'Looks like a bull'
-
- >>> class Mammoth(grok.Context):
- ... description = u'Looks like an elephant'
-
-Let's create now a page that will display their description.
-
- >>> from megrok.layout import Page
- >>> class AnimalDisplay(Page):
- ... grok.name('display')
- ... grok.context(Interface)
- ...
- ... def render(self):
- ... return self.context.description
-
-Grokking our Page will let us use it.
-
- >>> grok_component('AnimalDisplay', AnimalDisplay)
- True
- >>> wooly = Mammoth()
- >>> page = getMultiAdapter((wooly, TestRequest()), name='display')
- >>> page.render()
- u'Looks like an elephant'
- >>> page()
- u'a simple layout'
-
-As we can see, the page us using the layout, on the __call__ to
-render. Of course, this example Layout doesn't provide any
-interesting feature. Let's create something more interesting.
-
- >>> class MammothLayout(Layout):
- ... grok.context(Mammoth)
- ...
- ... def render(self):
- ... return u'Header. Page: %s. Footer' % self.view.render()
-
- >>> grok_component('MammothLayout', MammothLayout)
- True
- >>> page()
- u'Header. Page: Looks like an elephant. Footer'
-
Modified: megrok.layout/trunk/docs/HISTORY.txt
===================================================================
--- megrok.layout/trunk/docs/HISTORY.txt 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/docs/HISTORY.txt 2010-10-18 09:58:36 UTC (rev 117654)
@@ -1,8 +1,25 @@
Changelog
=========
+0.7 (2009-09-15)
+----------------
+
+- Add a CodePage to be compatible with the last version of
+ grokcore.view (higher than 1.9). This breaks compatibility with
+ previous release. You need to change any Page using a render method
+ to a CodePage.
+ [sylvain]
+
+- The content property on a Page is no longer a property, but a method
+ as it's hidding exceptions. You might need to update your code to
+ reflect that change as well.
+ [sylvain]
+
+- Fix MANIFEST.in.
+ [sylvain]
+
0.6 (2009-09-14)
-------------------
+----------------
- switch the arguments order in calling the layout
[cklinger, sylvain]
@@ -13,5 +30,5 @@
0.5 (2009-07-24)
----------------
-- remove the grok dependency
+- remove the grok dependency
[cklinger souheil]
Modified: megrok.layout/trunk/setup.py
===================================================================
--- megrok.layout/trunk/setup.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/setup.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -1,8 +1,8 @@
from setuptools import setup, find_packages
import os
-long_description = open('README.txt').read() + \
- '\n\n' + \
+readme_filename = os.path.join('src', 'megrok', 'layout', 'README.txt')
+long_description = open(readme_filename).read() + '\n\n' + \
open(os.path.join('docs', 'HISTORY.txt')).read()
@@ -32,9 +32,8 @@
install_requires=[
'setuptools',
'grokcore.component',
- 'grokcore.view',
+ 'grokcore.view >= 1.9',
'grokcore.formlib',
- # -*- Extra requirements: -*-
],
entry_points="""
# -*- Entry points: -*-
Modified: megrok.layout/trunk/src/megrok/layout/README.txt
===================================================================
--- megrok.layout/trunk/src/megrok/layout/README.txt 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/README.txt 2010-10-18 09:58:36 UTC (rev 117654)
@@ -8,19 +8,18 @@
Getting started
----------------
+===============
First we grok this package's grokkers::
>>> from megrok.layout import testing
>>> import grokcore.component as grok
- >>> from grokcore.component.testing import grok_component
>>> testing.grok('megrok.layout')
Layout
-------
+======
The layout is a component allowing you to design your site. Often,
it's the common structure shared between all the pages. Technically,
@@ -59,15 +58,16 @@
Now let's see how to use this Layout in a specific context using a Page.
-Page
-----
+Page and CodePage
+=================
-The page is the specific code that you want to control. It is based on
-the grokcore.View browser page implementation and therefore provides a
-'render' and 'update' method. The 'render' method will simply return the
-specific HTML code generated by the template or the 'render' method
-code while '__call__' will lookup for a Layout component and renders
-itself inside it.
+The Page is the specific code that you want to control. It is based on
+the grokcore.view.View browser page implementation and therefore
+provides a 'update' method, and a 'content' method that will return
+the specific HTML code generated by the template. If you don't whish
+to use a template, you can use a CodePage, in that case the 'content'
+method will return the result of the 'render' that you have to
+define. That last one works like grokcore.view.CodeView.
First, we'll create 2 models that will serve as exemples.
@@ -79,8 +79,8 @@
Let's create now a page that will display their description.
- >>> from megrok.layout import Page
- >>> class AnimalDisplay(Page):
+ >>> from megrok.layout import CodePage
+ >>> class AnimalDisplay(CodePage):
... grok.name('display')
... grok.context(Interface)
...
@@ -93,23 +93,24 @@
True
>>> wooly = Mammoth()
>>> page = getMultiAdapter((wooly, TestRequest()), name='display')
- >>> page.render()
+ >>> page.content()
u'Looks like an elephant'
>>> page()
u'a simple layout'
-As we can see, the page us using the layout, on the __call__ to
-render. Of course, this example Layout doesn't provide any
-interesting feature. Let's create something more interesting.
+As we can see, the page is using the layout, on the __call__ to
+render. Of course, this example Layout doesn't provide any interesting
+feature. Let's create something more interesting, by using our page
+with the help of the 'content' method:
>>> class MammothLayout(Layout):
... grok.context(Mammoth)
...
... def render(self):
- ... return u'Header. Page: %s. Footer' % self.view.render()
+ ... return u'Header. Page: %s. Footer' % self.view.content()
>>> grok_component('MammothLayout', MammothLayout)
True
>>> page()
u'Header. Page: Looks like an elephant. Footer'
-
+
Modified: megrok.layout/trunk/src/megrok/layout/__init__.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/__init__.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/__init__.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -1,2 +1,4 @@
-from megrok.layout.interfaces import ILayout, IPage
-from megrok.layout.components import Layout, Page, Form
+# -*- coding: utf-8 -*-
+
+from megrok.layout.interfaces import ILayout, IPage, ICodePage
+from megrok.layout.components import Layout, Page, CodePage, Form
Modified: megrok.layout/trunk/src/megrok/layout/components.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/components.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/components.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -6,7 +6,7 @@
import grokcore.component as grok
from zope.interface import Interface
from zope.publisher.publish import mapply
-from megrok.layout import IPage, ILayout
+from megrok.layout.interfaces import IPage, ICodePage, ILayout
class Layout(object):
@@ -61,51 +61,58 @@
return self.render()
-class Page(grokcore.view.View):
+class BasePage(object):
+ """A base page class.
+ """
+
+ def __init__(self, context, request):
+ super(BasePage, self).__init__(context, request)
+ self.layout = None
+
+ def __call__(self):
+ mapply(self.update, (), self.request)
+ if self.request.response.getStatus() in (302, 303):
+ # A redirect was triggered somewhere in update(). Don't
+ # continue rendering the template or doing anything else.
+ return
+ self.layout = zope.component.getMultiAdapter(
+ (self.request, self.context), ILayout)
+ return self.layout(self)
+
+
+class Page(BasePage, grokcore.view.View):
"""A view class.
"""
grok.baseclass()
grok.implements(IPage)
- template = None
-
- def __init__(self, context, request):
- super(Page, self).__init__(context, request)
- self.layout = None
-
def default_namespace(self):
namespace = super(Page, self).default_namespace()
namespace['layout'] = self.layout
return namespace
+ def content(self):
+ return self.template.render(self)
+
+
+class CodePage(BasePage, grokcore.view.CodeView):
+ """A code view class.
+ """
+ grok.baseclass()
+ grok.implements(ICodePage)
+
def render(self):
- return self._render_template()
+ raise NotImplementedError
- render.base_method = True
-
- @property
def content(self):
- template = getattr(self, 'template', None)
- if template is not None:
- return self._render_template()
return mapply(self.render, (), self.request)
- def __call__(self):
- mapply(self.update, (), self.request)
- if self.request.response.getStatus() in (302, 303):
- # A redirect was triggered somewhere in update(). Don't
- # continue rendering the template or doing anything else.
- return
- self.layout = zope.component.getMultiAdapter(
- (self.request, self.context), ILayout)
- return self.layout(self)
-
class Form(grokcore.formlib.Form):
"""A form class.
"""
grok.baseclass()
-
+
def __init__(self, context, request):
super(Form, self).__init__(context, request)
self.layout = None
@@ -115,13 +122,12 @@
namespace['layout'] = self.layout
return namespace
- @property
def content(self):
template = getattr(self, 'template', None)
if template is not None:
return self._render_template()
return mapply(self.render, (), self.request)
-
+
def __call__(self):
"""Calls update and returns the layout template which calls render.
"""
@@ -130,11 +136,11 @@
# A redirect was triggered somewhere in update(). Don't
# continue rendering the template or doing anything else.
return
-
+
self.update_form()
if self.request.response.getStatus() in (302, 303):
return
-
+
self.layout = zope.component.getMultiAdapter(
(self.request, self.context), ILayout)
return self.layout(self)
Modified: megrok.layout/trunk/src/megrok/layout/ftests/test_general.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/ftests/test_general.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/ftests/test_general.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -5,26 +5,34 @@
import zope.component.eventtesting
from zope import component
from megrok import layout
+from grokcore.component.testing import grok_component as default_grok_component
-
+
+def grok_component(name, component, **kwargs):
+ # Because of undocumented but ok change in grokcore.component,
+ # grok_component doesn't work anymore in doctests.
+ component.__grok_module__ = 'megrok.layout'
+ return default_grok_component(name, component, **kwargs)
+
+
def moduleSetUp(test):
module.setUp(test, '__main__')
-
-def moduleTearDown(test):
+
+def moduleTearDown(test):
module.tearDown(test)
cleanup.cleanUp()
-
+
def zopeSetUp(test):
zope.component.eventtesting.setUp(test)
def zopeTearDown(test):
cleanup.cleanUp()
-
+
def test_suite():
optionflags = doctest.NORMALIZE_WHITESPACE | doctest.ELLIPSIS
- globs = {}
+ globs = {'grok_component': grok_component}
suite = unittest.TestSuite()
-
+
suite.addTest(
doctest.DocFileSuite(
'../README.txt',
Modified: megrok.layout/trunk/src/megrok/layout/ftests/test_layout.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/ftests/test_layout.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/ftests/test_layout.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -23,7 +23,7 @@
import grokcore.component as grok
from zope import interface
-from megrok.layout import Layout
+from megrok.layout import Layout
class Mammoth(grok.Context):
@@ -55,4 +55,4 @@
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
)
suite.layer = FunctionalLayer
- return suite
+ return suite
Modified: megrok.layout/trunk/src/megrok/layout/ftests/test_layoutlayers.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/ftests/test_layoutlayers.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/ftests/test_layoutlayers.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -5,16 +5,16 @@
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
- >>> browser.handleErrors = False
-
- >>> browser.open("http://localhost/++skin++mydefaultskin/a/@@myview")
+ >>> browser.handleErrors = False
+
+ >>> browser.open("http://localhost/++skin++mydefaultskin/a/@@myview")
>>> print browser.contents
<div> A Layout </div>
- >>> browser.open("http://localhost/++skin++myskin/a/@@myview")
+ >>> browser.open("http://localhost/++skin++myskin/a/@@myview")
>>> print browser.contents
<div> A2 Layout </div>
-
+
>>> browser.open("http://localhost/++skin++myskin/b/@@myviewb")
>>> print browser.contents
<div> B Layout </div>
@@ -24,7 +24,7 @@
from grokcore.view import layer, skin
from zope import interface
-from megrok.layout import Layout, Page
+from megrok.layout import Layout, Page, CodePage
from grokcore.view import IDefaultBrowserLayer
@@ -79,14 +79,14 @@
return "<div> B Layout </div>"
-class MyView(Page):
+class MyView(CodePage):
grok.context(interface.Interface)
def render(self):
return "MYVIEW"
-class MyViewB(Page):
+class MyViewB(CodePage):
grok.context(interface.Interface)
layer(MySkinLayer)
@@ -101,4 +101,4 @@
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
)
suite.layer = FunctionalLayer
- return suite
+ return suite
Modified: megrok.layout/trunk/src/megrok/layout/ftests/test_page.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/ftests/test_page.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/ftests/test_page.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -15,12 +15,12 @@
</body>
</html>
-
+
>>> myview
<megrok.layout.ftests.test_page.MyView object at ...>
>>> myview.layout
<megrok.layout.ftests.test_page.Master object at ...>
- >>> print myview.content
+ >>> print myview.content()
<p> My nice Content </p>
"""
@@ -28,7 +28,7 @@
from grokcore.view import templatedir
from zope import interface
-from megrok.layout import Layout, Page
+from megrok.layout import Layout, Page, CodePage
templatedir('templates')
@@ -42,7 +42,7 @@
grok.context(Cow)
-class MyView(Page):
+class MyView(CodePage):
grok.context(interface.Interface)
def render(self):
@@ -56,4 +56,4 @@
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
)
suite.layer = FunctionalLayer
- return suite
+ return suite
Modified: megrok.layout/trunk/src/megrok/layout/ftests/test_specializedlayout.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/ftests/test_specializedlayout.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/ftests/test_specializedlayout.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -5,21 +5,21 @@
>>> from zope.testbrowser.testing import Browser
>>> browser = Browser()
>>> browser.addHeader('Authorization', 'Basic mgr:mgrpw')
- >>> browser.handleErrors = False
-
- >>> browser.open("http://localhost/++skin++askin/one/@@myview")
+ >>> browser.handleErrors = False
+
+ >>> browser.open("http://localhost/++skin++askin/one/@@myview")
>>> print browser.contents
<div> Layout A for context One </div>
- >>> browser.open("http://localhost/++skin++askin/two/@@myview")
+ >>> browser.open("http://localhost/++skin++askin/two/@@myview")
>>> print browser.contents
<div> Layout A for context Two </div>
- >>> browser.open("http://localhost/++skin++bskin/one/@@myview")
+ >>> browser.open("http://localhost/++skin++bskin/one/@@myview")
>>> print browser.contents
<div> Layout B for context One </div>
- >>> browser.open("http://localhost/++skin++bskin/two/@@myview")
+ >>> browser.open("http://localhost/++skin++bskin/two/@@myview")
>>> print browser.contents
<div> Layout B for context Two </div>
"""
@@ -28,7 +28,7 @@
from grokcore.view import layer, skin
from zope import interface
-from megrok.layout import Layout, Page
+from megrok.layout import Layout, Page, CodePage
from grokcore.view import IDefaultBrowserLayer
@@ -85,7 +85,7 @@
return "<div> Layout B for context Two </div>"
-class MyView(Page):
+class MyView(CodePage):
grok.context(interface.Interface)
grok.layer(IALayer)
@@ -100,4 +100,4 @@
optionflags=doctest.NORMALIZE_WHITESPACE|doctest.ELLIPSIS
)
suite.layer = FunctionalLayer
- return suite
+ return suite
Modified: megrok.layout/trunk/src/megrok/layout/interfaces.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/interfaces.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/interfaces.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -1,5 +1,6 @@
# -*- coding: utf-8 -*-
+from grokcore.view import interfaces
from zope.interface import Interface
@@ -7,6 +8,23 @@
"""Layout code.
"""
-class IPage(Interface):
+
+class IPageAware(Interface):
+ """A view which is able to use a layout to render itself.
+ """
+
+ def contents():
+ """Return the content of the page to be included in the
+ layout.
+ """
+
+
+class IPage(IPageAware, interfaces.IGrokView):
"""A template using a layout to render itself.
"""
+
+
+class ICodePage(IPage):
+ """A template using a layout to render itself.
+ """
+
Modified: megrok.layout/trunk/src/megrok/layout/meta.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/meta.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/meta.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -45,6 +45,6 @@
def has_no_render(factory):
render = getattr(factory, 'render', None)
base_method = getattr(render, 'base_method', False)
- return render is None or base_method
+ return render is None or base_method
templates.checkTemplates(module_info, factory, 'view',
has_render, has_no_render)
Modified: megrok.layout/trunk/src/megrok/layout/tests/test_norenderortemplatelayout.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/tests/test_norenderortemplatelayout.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/tests/test_norenderortemplatelayout.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -2,7 +2,7 @@
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
- ConfigurationExecutionError: <class 'martian.error.GrokError'>: View <class 'megrok.layout.tests.test_norenderortemplatelayout.MyLayout'> has no associated template or 'render' method.
+ ConfigurationExecutionError: martian.error.GrokError: View <class 'megrok.layout.tests.test_norenderortemplatelayout.MyLayout'> has no associated template.
in:
<BLANKLINE>
"""
Modified: megrok.layout/trunk/src/megrok/layout/tests/test_renderandtemplate.py
===================================================================
--- megrok.layout/trunk/src/megrok/layout/tests/test_renderandtemplate.py 2010-10-18 09:58:30 UTC (rev 117653)
+++ megrok.layout/trunk/src/megrok/layout/tests/test_renderandtemplate.py 2010-10-18 09:58:36 UTC (rev 117654)
@@ -1,8 +1,8 @@
"""
- >>> grok.testing.grok(__name__)
+ >>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
- ConfigurationExecutionError: <class 'martian.error.GrokError'>: Multiple possible ways to render view <class 'megrok.layout.tests.test_renderandtemplate.MyLayout'>. It has both a 'render' method as well as an associated template.
+ ConfigurationExecutionError: martian.error.GrokError: Multiple possible ways to render view <class 'megrok.layout.tests.test_renderandtemplate.MyLayout'>. It has both a 'render' method as well as an associated template.
in:
<BLANKLINE>
"""
More information about the checkins
mailing list