work in progress: cybertools.reporter

git-svn-id: svn://svn.cy55.de/Zope3/src/cybertools/trunk@1748 fd906abe-77d9-0310-91a1-e0d9ade77398
This commit is contained in:
helmutm 2007-05-20 17:07:17 +00:00
parent 36f0f335ce
commit a0a52ab055
7 changed files with 170 additions and 105 deletions

View file

@ -1,19 +1,54 @@
Quickstart Instructions
=======================
====================================
A Basic API for Reports and Listings
====================================
($Id$)
TO DO...
>>> from zope.app import zapi
>>> from zope.app.testing import ztapi
>>> from zope import component
>>> from zope.interface import directlyProvides
A Basic API for Reports and Listings
====================================
Listings
========
>>> from cybertools.reporter.data import DataSource
>>> from cybertools.reporter.resultset import ResultSet
>>> from cybertools.reporter.interfaces import IResultSet
Let's start with the Person class from the cybertools.organize package - we will
then provide a listing of persons...
>>> from cybertools.organize.party import Person
>>> from datetime import date
>>> pdata = ((u'John', u'Smith', '1956-08-01'),
... (u'David', u'Waters', '1972-12-24'),
... (u'Carla', u'Myers', '1981-10-11'))
>>> persons = DataSource([Person(f, s, date(*[int(d) for d in b.split('-')]))
... for f, s, b in pdata])
>>> component.provideAdapter(ResultSet)
>>> rset = IResultSet(persons)
>>> len(list(rset.rows))
3
For the browser presentation we can also use a browser view providing
the result set with extended attributes:
>>> #rsView = component.getMultiAdapter((context, TestRequest()), IBrowserView)
The reporter package also includes facilities for sorting the rows in a
result set and splitting a result into batches.
Sorting
-------
Batching
--------
========
We'll use a fairly simple Iterable:
@ -48,43 +83,4 @@ We are now ready to use the corresponding browser view:
'navOnClick': "dojo.io.updateNode(...); return false;",
'title': 5}
The real reporting stuff
------------------------
>>> from cybertools.reporter.data import DataSource
>>> from cybertools.reporter.interfaces import IResultSet
>>> from cybertools.reporter.example.interfaces import IContactsDataSource
>>> from cybertools.reporter.example.contact import Contacts
Let's start with the Person class from the example package - we will
then provide a listing of persons...
>>> from cybertools.organize.party import Person
>>> from datetime import date
>>> pdata = ((u'John', u'Smith', '1956-08-01'),
... (u'David', u'Waters', '1972-12-24'),
... (u'Carla', u'Myers', '1981-10-11'))
>>> persons = DataSource([Person(f, s, date(*[int(d) for d in b.split('-')]))
... for f, s, b in pdata])
>>> directlyProvides(persons, IContactsDataSource)
>>> ztapi.provideAdapter(IContactsDataSource, IResultSet, Contacts)
>>> rset = IResultSet(persons)
>>> len(rset)
3
For the browser presentation we can also use a browser view providing
the result set with extended attributes:
>>> #rsView = zapi.getMultiAdapter((context, TestRequest()), IBrowserView)
The reporter package also includes facilities for sorting the rows in a
result set and splitting a result into batches.
Sorting
-------

View file

@ -0,0 +1,41 @@
<!-- $Id$ -->
<metal:detail define-macro="detail">
<h2 tal:content="item/title">Something</h2><br />
<table>
<tr tal:repeat="cell item/cells">
<td><span tal:content="cell/title"
i18n:translate="" />Fieldname:</td>
<td tal:content="cell/text">Value</td>
</tr>
</table>
</metal:detail>
<metal:listing define-macro="listing"
tal:define="result item/resultSet">
<h2 tal:content="item/title">Something</h2><br />
<table class="listing">
<tr>
<th tal:repeat="field result/schema"
tal:content="field/title"
i18n:translate="">Fieldname</th>
</tr>
<tal:items repeat="row result/rows">
<tal:item define="class python: repeat['row'].odd() and 'even' or 'odd'">
<tr tal:attributes="class class">
<td valign="top"
repeat="cell row/cells">
<a href="#"
tal:omit-tag="not: cell/url"
tal:attributes="href cell/url;
title cell/urlTitle">
<span tal:replace="cell/text">Value</span>
</a>
</td>
</tr>
</tal:item>
</tal:items>
</table>
</metal:listing>

View file

@ -0,0 +1,65 @@
#
# Copyright (c) 2007 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
#
"""
View classes for reports.
$Id$
"""
from zope import interface, component
from zope.app.pagetemplate import ViewPageTemplateFile
from zope.cachedescriptors.property import Lazy
from loops.browser.common import BaseView
reportMacros = ViewPageTemplateFile('macros.pt')
class DetailView(BaseView):
template = reportMacros
@Lazy
def macro(self):
return self.template.macros('detail')
@Lazy
def resultSet(self):
result = ResultSet()
return result
@Lazy
def cells(self):
return self.resultSet.rows.next()
class ListingView(BaseView):
template = reportMacros
@Lazy
def macro(self):
return self.template.macros('listing')
@Lazy
def resultSet(self):
result = ResultSet()
return result

View file

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

View file

@ -1,31 +0,0 @@
#
# 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 an example for the cybertools.reporter package. This is
based on the cybertools.contact package
$Id$
"""
from zope.interface import Interface
class IContactsDataSource(Interface):
""" A data source marker interface for a collection of contacts.
"""

View file

@ -36,7 +36,7 @@ class IBatch(Interface):
iterable = Attribute(u'The iterable this batch belongs to')
start = Attribute(u'The current start index of the batch in the parent iterable')
def __getitem__(idx):
""" Return the item at index idx on the current page.
"""
@ -74,38 +74,37 @@ class IResultSet(Interface):
(fields, cells).
"""
schema = zope.schema.Iterable(title=u'Schema',
description=u'Collection of field specifications based '
'on the interfaces defined by zope.schema.')
rows = zope.schema.Iterable(title=u'Rows',
description=u'Sequence of row objects')
schema = Attribute(u'Collection of field specifications from zope.schema.')
rows = Attribute(u'Sequence of row objects.')
view = Attribute(u'The view the result set was created for.')
class IRow(Interface):
""" A sequence of cells containing the real data objects.
"""
cells = zope.schema.Dict(zope.schema.ASCIILine(),
title=u'Cells',
description=u'Mapping of data elements addressed by a name '
'that is the key to the mapping.')
cells = Attribute(u'Mapping of data elements addressed by field names.')
value = Attribute(u'The object that is the base of this row.')
resultSet = Attribute('The result set this row belongs to.')
schema = Attribute(u'The schema of the result set this row belongs to')
class ICell(Interface):
""" A single cell of a listing or table.
"""
text = zope.schema.Text(title=u'Text',
description=u'Text to be displayed')
value = zope.schema.Object(Interface,
title=u'Value',
description=u'The real object, often identical to text.')
token = zope.schema.ASCIILine(title=u'Token',
description=u'May be used to identify a cell within'
'the result set, e.g. in forms')
text = Attribute(u'Text to be displayed.')
value = Attribute(u'The real object, often identical to text.')
token = Attribute(u'May be used to identify a cell within '
'the result set, e.g. in forms.')
url = Attribute(u'An optional URL for a link to place on the cell.')
# string:${view/url}/.target${row/uniqueId}
urlTitle = Attribute(u'Optional title for this link.')
title = Attribute('The title of the schema field this cell belongs to.')
row = Attribute('The row this cell belongs to.')
def sortKey():

View file

@ -27,8 +27,8 @@ $Id$
from zope.component import adapts
from zope.interface import implements
from cybertools.reporter.interfaces import IDataSource
from cybertools.reporter.interfaces import IResultSet, IRow, ICell
from cybertools.reporter.example.interfaces import IContactsDataSource
class Cell(object):
@ -69,10 +69,10 @@ class Row(object):
for f in schema.fields])
class Contacts(object):
class ResultSet(object):
implements(IResultSet)
adapts(IContactsDataSource)
adapts(IDataSource)
def __init__(self, context):
self.context = context
@ -84,7 +84,6 @@ class Contacts(object):
@property
def rows(self):
return [Row(o, self) for o in iter(self.context)]
for o in iter(self.context):
yield Row(o, self)
def __len__(self):
return len(self.rows)