renamed 'schemaMacros' attribute to 'fieldRenderers'; start with adapter-based registration of renderers (=macros for standard browser UIs)

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@2088 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-10-07 13:15:00 +00:00
parent 1747ce67e2
commit 31bddf189d
5 changed files with 103 additions and 54 deletions

38
browser/interfaces.py Normal file
View file

@ -0,0 +1,38 @@
#
# Copyright (c) 2006 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
#
"""
Interfaces for the cybertools.browser package.
$Id$
"""
from zope.interface import Interface, Attribute
class IRenderers(Interface):
""" Provides a dictionary of renderers.
A typical implementation is provided by the ``macros`` attribute
of a Zope Page Template.
"""
class IRenderer(Interface):
""" Marker interface for a renderer, e.g. a ZPT macro.
"""

View file

@ -161,3 +161,10 @@ Create a new object using a schema-based form
>>> p2.lastName, p2.age >>> p2.lastName, p2.age
(u'Smith', 28) (u'Smith', 28)
Macros / renderers
------------------
>>> fieldRenderers = form.fieldRenderers
>>> sorted(fieldRenderers.keys())
[u'field', u'field_spacer', u'fields', u'input_dropdown', u'input_fileupload',
u'input_password', u'input_textarea', u'input_textline']

View file

@ -22,7 +22,7 @@ View(s) for forms based on composer.schema.
$Id$ $Id$
""" """
from zope import component from zope import component, interface
from zope.app.container.interfaces import INameChooser from zope.app.container.interfaces import INameChooser
from zope.cachedescriptors.property import Lazy from zope.cachedescriptors.property import Lazy
from zope.interface import Interface from zope.interface import Interface
@ -30,6 +30,7 @@ from zope.event import notify
from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent from zope.lifecycleevent import ObjectCreatedEvent, ObjectModifiedEvent
from zope.traversing.browser.absoluteurl import absoluteURL from zope.traversing.browser.absoluteurl import absoluteURL
from cybertools.browser.interfaces import IRenderers
from cybertools.composer.interfaces import IInstance from cybertools.composer.interfaces import IInstance
from cybertools.composer.schema.browser.common import schema_macros, schema_edit_macros from cybertools.composer.schema.browser.common import schema_macros, schema_edit_macros
from cybertools.composer.schema.interfaces import ISchemaFactory from cybertools.composer.schema.interfaces import ISchemaFactory
@ -47,12 +48,17 @@ class Form(object):
self.context = context self.context = context
self.request = request self.request = request
@property @Lazy
def schemaMacros(self): def schemaMacros(self):
return schema_macros.macros return schema_macros.macros
@property # proof-of-concept - get a dictionary of renderers (macros) via adaptatation
def schemaEditMacros(self): @Lazy
def fieldRenderers(self):
return IRenderers(self)
@Lazy
def fieldEditRenderers(self):
return schema_edit_macros.macros return schema_edit_macros.macros
@Lazy @Lazy
@ -151,3 +157,12 @@ class CreateForm(Form):
def getName(self, obj): def getName(self, obj):
name = getattr(obj, 'name', getattr(obj, 'title')) name = getattr(obj, 'name', getattr(obj, 'title'))
return INameChooser(container).chooseName(name, obj) return INameChooser(container).chooseName(name, obj)
# proof-of-concept - define a dictionary of renderers (macros) as an adapter
@interface.implementer(IRenderers)
@component.adapter(Form)
def getFormSchemaRenderers(view):
return schema_macros.macros
component.provideAdapter(getFormSchemaRenderers)

View file

@ -11,12 +11,12 @@
<tal:fields repeat="field fields"> <tal:fields repeat="field fields">
<tal:field define="name field/name; <tal:field define="name field/name;
errors state/fieldInstances/?name/errors|python: [];"> errors state/fieldInstances/?name/errors|python: [];">
<metal:field use-macro="python: view.schemaMacros[field.fieldRenderer]" /> <metal:field use-macro="python: view.fieldRenderers[field.fieldRenderer]" />
</tal:field> </tal:field>
</tal:fields> </tal:fields>
</table> </table>
<tal:add condition="manageMode"> <tal:add condition="manageMode">
<metal:add use-macro="view/schemaEditMacros/add_buttons" /> <metal:add use-macro="view/fieldEditRenderers/add_buttons" />
</tal:add> </tal:add>
</tal:define> </tal:define>
</metal:fields> </metal:fields>
@ -42,17 +42,17 @@
</td> </td>
<td class="field" style="border-top: none"> <td class="field" style="border-top: none">
<metal:input use-macro="python: <metal:input use-macro="python:
view.schemaMacros[field.inputRenderer]" /> view.fieldRenderers[field.inputRenderer]" />
</td> </td>
</tal:field> </tal:field>
</tr> </tr>
<tr style="border-bottom: 1px solid #dddddd" <tr style="border-bottom: 1px solid #dddddd"
tal:condition="manageMode"> tal:condition="manageMode">
<td style="border-top: none"> <td style="border-top: none">
<metal:move use-macro="view/editMacros/move_icons" /> <metal:move use-macro="view/fieldEditRenderers/move_icons" />
</td> </td>
<td style="border-top: none"> <td style="border-top: none">
<metal:edit use-macro="view/schemaEditMacros/edit_buttons" /> <metal:edit use-macro="view/fieldEditRenderers/edit_buttons" />
</td> </td>
</tr> </tr>
</tbody> </tbody>
@ -69,6 +69,16 @@
</metal:textline> </metal:textline>
<metal:password define-macro="input_password">
<input type="password" name="field" style="width: 450px"
tal:define="width field/width|nothing"
tal:attributes="name name;
style python:
'width: %s' % (width and str(width)+'px' or '450px');
value data/?name" />
</metal:password>
<metal:textarea define-macro="input_textarea"> <metal:textarea define-macro="input_textarea">
<textarea name="field" rows="3" style="width: 450px" <textarea name="field" rows="3" style="width: 450px"
tal:define="width field/width|nothing; tal:define="width field/width|nothing;
@ -118,10 +128,10 @@
<tr style="border-bottom: 1px solid #dddddd" <tr style="border-bottom: 1px solid #dddddd"
tal:condition="manageMode"> tal:condition="manageMode">
<td style="border-top: none"> <td style="border-top: none">
<metal:move use-macro="view/schemaEditMacros/move_icons" /> <metal:move use-macro="view/fieldEditRenderers/move_icons" />
</td> </td>
<td style="border-top: none"> <td style="border-top: none">
<metal:edit use-macro="view/schemaEditMacros/edit_buttons" /> <metal:edit use-macro="view/fieldEditRenderers/edit_buttons" />
</td> </td>
</tr> </tr>
</metal:spacer> </metal:spacer>

View file

@ -75,7 +75,8 @@
batch nocall:context/@@cybertools.reporter.batch; batch nocall:context/@@cybertools.reporter.batch;
batch python:batch.setup(container_contents)"> batch python:batch.setup(container_contents)">
<tal:list repeat="item batch/items"> <tal:list repeat="item batch/items">
<tr tal:define="oddrow repeat/item/odd; url item/url; <tr tal:define="oddrow repeat/item/odd;
url item/url;
id_quoted item/id/url:quote" id_quoted item/id/url:quote"
tal:attributes="class python:oddrow and 'even' or 'odd'" > tal:attributes="class python:oddrow and 'even' or 'odd'" >
<td> <td>
@ -85,45 +86,27 @@
id item/cb_id; id item/cb_id;
checked request/ids_checked|nothing;"/> checked request/ids_checked|nothing;"/>
</td> </td>
<td><a href="#" <td>
tal:attributes="href <a href="#"
string:${url}/@@SelectedManagementView.html" tal:attributes="href string:${url}/@@SelectedManagementView.html"
tal:content="structure item/icon|default"> tal:content="structure item/icon|default"></a>
</a <span tal:condition="item/rename">
><span tal:condition="item/rename" <input name="new_value:list"
><input name="new_value:list" tal:attributes="value item/id"/>
tal:attributes="value item/id" <input type="hidden" name="rename_ids:list" value=""
/><input type="hidden" name="rename_ids:list" value="" tal:attributes="value item/rename" />
tal:attributes="value item/rename" </span>
/></span <span tal:condition="not:item/rename">
><span tal:condition="not:item/rename">
<a href="#" <a href="#"
tal:attributes="href tal:attributes="href
string:${url}/@@SelectedManagementView.html" string:${url}/@@SelectedManagementView.html"
tal:content="item/id" tal:content="item/id">foo</a>
>foo</a </span>
><a href="#" </td>
tal:attributes="href
string:${request/URL}?rename_ids:list=${id_quoted}"
tal:condition="supportsRename"
>&nbsp;&nbsp;</a
></span
></td>
<td> <td>
<input name="new_value" id="focusid"
tal:attributes="value item/title|nothing"
tal:condition="item/retitle"
/>
<a href="#" <a href="#"
tal:attributes="href tal:attributes="href string:${url}/@@SelectedManagementView.html"
string:${request/URL}?retitle_id=${id_quoted}" tal:content="item/title|default">Title</a>
tal:condition="item/retitleable"
tal:content="item/title|default"
>&nbsp;&nbsp;&nbsp;&nbsp;</a>
<span
tal:condition="item/plaintitle"
tal:content="item/title|default"
>&nbsp;&nbsp;&nbsp;&nbsp;</span>
</td> </td>
<td><span tal:content="item/size/sizeForDisplay|nothing" <td><span tal:content="item/size/sizeForDisplay|nothing"
@ -151,26 +134,22 @@
next batch/next/title; next batch/next/title;
last batch/last/title;"> last batch/last/title;">
<a href="#" <a href="#"
tal:attributes="href batch/first/url; tal:attributes="href batch/first/url;"
onclick batch/first/navOnClick"
tal:content="first" tal:content="first"
tal:condition="python: first != current">1</a> tal:condition="python: first != current">1</a>
<span tal:condition="python: first &lt; previous-1">...</span> <span tal:condition="python: first &lt; previous-1">...</span>
<a href="#" <a href="#"
tal:attributes="href batch/previous/url; tal:attributes="href batch/previous/url;"
onclick batch/previous/navOnClick"
tal:content="batch/previous/title" tal:content="batch/previous/title"
tal:condition="python: first != previous and previous != current">2</a> tal:condition="python: first != previous and previous != current">2</a>
<b tal:content="batch/current/title">3</b> <b tal:content="batch/current/title">3</b>
<a href="#" <a href="#"
tal:attributes="href batch/next/url; tal:attributes="href batch/next/url;"
onclick batch/next/navOnClick"
tal:content="batch/next/title" tal:content="batch/next/title"
tal:condition="python: last != next and next != current">3</a> tal:condition="python: last != next and next != current">3</a>
<span tal:condition="python: last > next+1">...</span> <span tal:condition="python: last > next+1">...</span>
<a href="#" <a href="#"
tal:attributes="href batch/last/url; tal:attributes="href batch/last/url;"
onclick batch/last/navOnClick"
tal:content="batch/last/title" tal:content="batch/last/title"
tal:condition="python: last != current">5</a> tal:condition="python: last != current">5</a>
</metal:nav> </metal:nav>