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:
parent
996846f711
commit
3c3d635493
13 changed files with 345 additions and 10 deletions
|
@ -63,8 +63,8 @@ class IInstance(Interface):
|
||||||
|
|
||||||
context = Attribute('Object this instance adapter has been created for')
|
context = Attribute('Object this instance adapter has been created for')
|
||||||
template = Attribute('A template to be used for this instance')
|
template = Attribute('A template to be used for this instance')
|
||||||
aspect = Attribute('A dotted name that helps to store and retrieve the '
|
aspect = Attribute('Optional: a dotted name that may help to store and '
|
||||||
'template.')
|
'retrieve the template.')
|
||||||
|
|
||||||
def applyTemplate(*args, **kw):
|
def applyTemplate(*args, **kw):
|
||||||
""" Apply the template using the instance's context. Note that this
|
""" Apply the template using the instance's context. Note that this
|
||||||
|
|
|
@ -4,5 +4,41 @@ Layout Management
|
||||||
|
|
||||||
($Id$)
|
($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>...
|
||||||
|
|
|
@ -26,7 +26,8 @@ from zope.interface import implements
|
||||||
|
|
||||||
from cybertools.composer.base import Component, Element, Compound
|
from cybertools.composer.base import Component, Element, Compound
|
||||||
from cybertools.composer.base import Template
|
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
|
from cybertools.util.jeep import Jeep
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,4 +37,32 @@ class Layout(Template):
|
||||||
|
|
||||||
name = u''
|
name = u''
|
||||||
manager = None
|
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 []
|
||||||
|
|
||||||
|
|
3
composer/layout/browser/__init__.py
Normal file
3
composer/layout/browser/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
"""
|
||||||
|
$Id$
|
||||||
|
"""
|
1
composer/layout/browser/base.pt
Normal file
1
composer/layout/browser/base.pt
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<metal:render use-macro="nocall:view/renderer" />
|
37
composer/layout/browser/layout.py
Normal file
37
composer/layout/browser/layout.py
Normal 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']
|
||||||
|
|
3
composer/layout/browser/liquid/__init__.py
Normal file
3
composer/layout/browser/liquid/__init__.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
"""
|
||||||
|
$Id$
|
||||||
|
"""
|
37
composer/layout/browser/liquid/body.pt
Normal file
37
composer/layout/browser/liquid/body.pt
Normal 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>
|
22
composer/layout/browser/main.pt
Normal file
22
composer/layout/browser/main.pt
Normal 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>
|
3
composer/layout/browser/standard.pt
Normal file
3
composer/layout/browser/standard.pt
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
<div metal:define-macro="footer">
|
||||||
|
Some footer text.
|
||||||
|
</div>
|
97
composer/layout/browser/view.py
Normal file
97
composer/layout/browser/view.py
Normal 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 []
|
|
@ -1,4 +1,4 @@
|
||||||
#
|
|
||||||
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
# Copyright (c) 2008 Helmut Merz helmutm@cy55.de
|
||||||
#
|
#
|
||||||
# This program is free software; you can redistribute it and/or modify
|
# 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 zope.schema.vocabulary import SimpleVocabulary, SimpleTerm
|
||||||
|
|
||||||
from cybertools.composer.interfaces import ITemplate, IComponent
|
from cybertools.composer.interfaces import ITemplate, IComponent
|
||||||
from cybertools.composer.interfaces import IInstance as IBaseInstance
|
from cybertools.composer.interfaces import IInstance
|
||||||
|
|
||||||
_ = MessageFactory('cybertools.composer')
|
_ = MessageFactory('cybertools.composer')
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ class ILayout(ITemplate):
|
||||||
""" Represents an ordered sequence of layout elements.
|
""" Represents an ordered sequence of layout elements.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = schema.ASCII(
|
name = schema.ASCIILine(
|
||||||
title=_(u'Layout name'),
|
title=_(u'Layout name'),
|
||||||
description=_(u'The internal name of the layout.'),
|
description=_(u'The internal name of the layout.'),
|
||||||
required=True,)
|
required=True,)
|
||||||
|
@ -49,13 +49,20 @@ class ILayout(ITemplate):
|
||||||
title=_(u'Description'),
|
title=_(u'Description'),
|
||||||
description=_(u'A medium-length description.'),
|
description=_(u'A medium-length description.'),
|
||||||
required=False,)
|
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):
|
class ILayoutComponent(IComponent):
|
||||||
""" May be used for data entry or display.
|
""" May be used for data entry or display.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
name = schema.ASCII(
|
name = schema.ASCIILine(
|
||||||
title=_(u'Component name'),
|
title=_(u'Component name'),
|
||||||
description=_(u'The internal name of the component'),
|
description=_(u'The internal name of the component'),
|
||||||
required=True,)
|
required=True,)
|
||||||
|
@ -73,10 +80,29 @@ class ILayoutComponent(IComponent):
|
||||||
u'or a listing, ...')
|
u'or a listing, ...')
|
||||||
|
|
||||||
|
|
||||||
class ILayoutInstance(IBaseInstance):
|
class ILayoutInstance(IInstance):
|
||||||
""" An instance adapter for an arbitrary client object that associates
|
""" An instance adapter for an arbitrary client object that associates
|
||||||
it with a layout.
|
it with a layout.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
renderer = Attribute(u'An object responsible for rendering the layout.')
|
||||||
|
|
||||||
componentAttributes = Attribute(u'A mapping``{componentName: value, ...}`` '
|
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
41
composer/layout/region.py
Normal 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 = {}
|
Loading…
Add table
Reference in a new issue