work in progress: layout management

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2783 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2008-07-31 11:18:28 +00:00
parent 996846f711
commit 3c3d635493
13 changed files with 345 additions and 10 deletions

View file

@ -63,8 +63,8 @@ class IInstance(Interface):
context = Attribute('Object this instance adapter has been created for')
template = Attribute('A template to be used for this instance')
aspect = Attribute('A dotted name that helps to store and retrieve the '
'template.')
aspect = Attribute('Optional: a dotted name that may help to store and '
'retrieve the template.')
def applyTemplate(*args, **kw):
""" Apply the template using the instance's context. Note that this

View file

@ -4,5 +4,41 @@ Layout Management
($Id$)
>>> from cybertools.composer.layout.base import Layout
>>> from zope import component
>>> from zope.interface import Interface
>>> from cybertools.composer.layout.base import Layout, LayoutInstance
>>> from cybertools.composer.layout.region import Region, regions
Browser Views
=============
>>> from zope.traversing.adapters import DefaultTraversable
>>> component.provideAdapter(DefaultTraversable, (Interface,))
>>> from cybertools.composer.layout.browser.layout import PageLayout
>>> pageLayout = PageLayout()
>>> pageLayoutInstance = LayoutInstance(pageLayout)
>>> from zope.app.pagetemplate import ViewPageTemplateFile
>>> bodyLayout = Layout()
>>> bodyLayout.renderer = ViewPageTemplateFile('browser/liquid/body.pt').macros['body']
>>> bodyRegion = Region('body')
>>> bodyRegion.layouts.append(LayoutInstance(bodyLayout))
>>> regions['page.body'] = bodyRegion
>>> standardRenderers = ViewPageTemplateFile('browser/standard.pt').macros
>>> footerLayout = Layout()
>>> footerLayout.renderer = standardRenderers['footer']
>>> footerRegion = Region('footer')
>>> footerRegion.layouts.append(LayoutInstance(footerLayout))
>>> regions['body.footer'] = footerRegion
>>> from cybertools.composer.layout.browser.view import Page
>>> from zope.publisher.browser import TestRequest
>>> page = Page(pageLayoutInstance, TestRequest())
>>> page()
u'<!DOCTYPE ...>...<html ...>...</html>...

View file

@ -26,7 +26,8 @@ from zope.interface import implements
from cybertools.composer.base import Component, Element, Compound
from cybertools.composer.base import Template
from cybertools.composer.layout.interfaces import ILayout
from cybertools.composer.layout.interfaces import ILayout, ILayoutInstance
from cybertools.composer.layout.interfaces import IRegion
from cybertools.util.jeep import Jeep
@ -36,4 +37,32 @@ class Layout(Template):
name = u''
manager = None
renderer = None
class LayoutInstance(object):
implements(ILayoutInstance)
def __init__(self, template, context=None):
self.template = template
self.context = context
@property
def renderer(self):
return self.template.renderer
class Region(object):
implements(IRegion)
allowedLayoutCategories = None
def __init__(self, name):
self.name = name
@property
def layouts(self):
return []

View file

@ -0,0 +1,3 @@
"""
$Id$
"""

View file

@ -0,0 +1 @@
<metal:render use-macro="nocall:view/renderer" />

View file

@ -0,0 +1,37 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Specialized browser layouts.
$Id$
"""
from zope.app.pagetemplate import ViewPageTemplateFile
from cybertools.composer.layout.base import Layout
class PageLayout(Layout):
name = u'page'
@property
def renderer(self):
return ViewPageTemplateFile('main.pt').macros['page']

View file

@ -0,0 +1,3 @@
"""
$Id$
"""

View file

@ -0,0 +1,37 @@
<body class="tundra"
metal:define-macro="body">
<!--<div id="global">
<div class="top">
<tal:sub repeat="view view/layouts/logo">
<metal:sub use-macro="view/renderer" /></tal:sub>
<tal:sub repeat="view view/layouts/top_actions">
<metal:sub use-macro="view/renderer" /></tal:sub>
</div>
</div>
<div id="menu">
<tal:sub repeat="view view/layouts/portlets_left">
<metal:sub use-macro="view/renderer" />
</tal:sub>
</div>
<div id="content">
<tal:sub repeat="view view/layouts/content">
<metal:sub use-macro="view/renderer" />
</tal:sub>
</div>
<div id="sub-section">
<tal:sub repeat="view view/layouts/portlets_right">
<metal:sub use-macro="view/renderer" />
</tal:sub>
</div>-->
<div id="footer" class="footer">
<tal:sub repeat="view view/layouts/footer">
<metal:sub use-macro="view/renderer" />
</tal:sub>
</div>
</body>

View file

@ -0,0 +1,22 @@
<metal:page define-macro="page"><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"
tal:define="body view/body">
<head metal:define-macro="head">
<title metal:define-macro="title"
tal:content="options/title|view/headTitle|context/title|default">
Powered by Zope 3
</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<tal:css repeat="macro view/resources/css">
<metal:css use-macro="macro" />
</tal:css>
<base href="." tal:attributes="href request/URL">
</head>
<body tal:replace="structure body" />
</html>
</metal:page>

View file

@ -0,0 +1,3 @@
<div metal:define-macro="footer">
Some footer text.
</div>

View file

@ -0,0 +1,97 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Basic view classes for layout-based presentation.
$Id$
"""
from zope import component
from zope.interface import Interface, implements
from zope.cachedescriptors.property import Lazy
from zope.app.pagetemplate import ViewPageTemplateFile
from cybertools.composer.layout.region import regions
class BaseView(object):
template = ViewPageTemplateFile('base.pt')
def __init__(self, context, request, name=None):
self.context = self.__parent__ = context
self.request = request
if name is not None:
self.name = name
def update(self):
return True
def __call__(self):
return self.template(self)
class LayoutView(BaseView):
name = 'base'
@Lazy
def renderer(self):
return self.context.renderer
@Lazy
def layouts(self):
return ViewLayouts(self)
@Lazy
def resources(self):
return ViewResources(self)
def getRegion(self, key):
return regions['.'.join((self.name, key))]
class Page(LayoutView):
name = 'page'
#@Lazy
def body(self):
return self.layouts['body'][0]()
class ViewLayouts(object):
def __init__(self, view):
self.view = view
def __getitem__(self, key):
view = self.view
region = view.getRegion(key)
return [LayoutView(layout, view.request, name=key)
for layout in region.layouts]
class ViewResources(object):
def __init__(self, view):
self.view = view
def __getitem__(self, key):
return []

View file

@ -1,4 +1,4 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
@ -28,7 +28,7 @@ from zope import schema
from zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
from cybertools.composer.interfaces import ITemplate, IComponent
from cybertools.composer.interfaces import IInstance as IBaseInstance
from cybertools.composer.interfaces import IInstance
_ = MessageFactory('cybertools.composer')
@ -37,7 +37,7 @@ class ILayout(ITemplate):
""" Represents an ordered sequence of layout elements.
"""
name = schema.ASCII(
name = schema.ASCIILine(
title=_(u'Layout name'),
description=_(u'The internal name of the layout.'),
required=True,)
@ -49,13 +49,20 @@ class ILayout(ITemplate):
title=_(u'Description'),
description=_(u'A medium-length description.'),
required=False,)
category = schema.ASCIILine(
title=_(u'Layout category'),
description=_(u'The name of a layout category this layout '
u'belongs to.'),
required=False,)
renderer = Attribute(u'An object responsible for rendering the layout.')
class ILayoutComponent(IComponent):
""" May be used for data entry or display.
"""
name = schema.ASCII(
name = schema.ASCIILine(
title=_(u'Component name'),
description=_(u'The internal name of the component'),
required=True,)
@ -73,10 +80,29 @@ class ILayoutComponent(IComponent):
u'or a listing, ...')
class ILayoutInstance(IBaseInstance):
class ILayoutInstance(IInstance):
""" An instance adapter for an arbitrary client object that associates
it with a layout.
"""
renderer = Attribute(u'An object responsible for rendering the layout.')
componentAttributes = Attribute(u'A mapping``{componentName: value, ...}`` '
u'specifying the parameter values entered for the components.')
u'specifying the parameter values entered for the components. '
u'If a component is a layout the value is a corresponding '
u'layout instance.')
class IRegion(Interface):
""" A part of a layout "canvas" that may be filled with layout objects.
"""
allowedLayoutCategories = schema.List(
title=_(u'Allowed layout categories'),
description=_(u'A collection of names of layout categories '
u'to which layouts may belong that may be placed '
u'in this region'),
value_type=schema.ASCIILine(),
required=False,)
layouts = Attribute(u'The layout instances currently assigned to this region.')

41
composer/layout/region.py Normal file
View file

@ -0,0 +1,41 @@
#
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
"""
Region class(es) + default regions registry.
$Id$
"""
from zope.interface import implements
from cybertools.composer.layout.interfaces import IRegion
class Region(object):
implements(IRegion)
allowedLayoutCategories = None
def __init__(self, name):
self.name = name
self.layouts = []
regions = {}