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:
parent
36f0f335ce
commit
a0a52ab055
7 changed files with 170 additions and 105 deletions
|
@ -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
|
||||
-------
|
||||
|
||||
|
||||
|
|
41
reporter/browser/macros.pt
Normal file
41
reporter/browser/macros.pt
Normal 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>
|
||||
|
65
reporter/browser/report.py
Normal file
65
reporter/browser/report.py
Normal 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
|
||||
|
|
@ -1,4 +0,0 @@
|
|||
"""
|
||||
$Id$
|
||||
"""
|
||||
|
|
@ -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.
|
||||
"""
|
||||
|
|
@ -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():
|
||||
|
|
|
@ -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)
|
Loading…
Add table
Reference in a new issue