diff --git a/reporter/README.txt b/reporter/README.txt
index 0dd5e71..13d7b8e 100644
--- a/reporter/README.txt
+++ b/reporter/README.txt
@@ -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
--------
-
diff --git a/reporter/browser/macros.pt b/reporter/browser/macros.pt
new file mode 100644
index 0000000..2f342e0
--- /dev/null
+++ b/reporter/browser/macros.pt
@@ -0,0 +1,41 @@
+
+
+
+ Something
+
+
+ Fieldname: |
+ Value |
+
+
+
+
+
+
+ Something
+
+
+ Fieldname |
+
+
+
+
+
+
+ Value
+
+ |
+
+
+
+
+
+
diff --git a/reporter/browser/report.py b/reporter/browser/report.py
new file mode 100644
index 0000000..fea9dd6
--- /dev/null
+++ b/reporter/browser/report.py
@@ -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
+
diff --git a/reporter/example/__init__.py b/reporter/example/__init__.py
deleted file mode 100644
index 4bc90fb..0000000
--- a/reporter/example/__init__.py
+++ /dev/null
@@ -1,4 +0,0 @@
-"""
-$Id$
-"""
-
diff --git a/reporter/example/interfaces.py b/reporter/example/interfaces.py
deleted file mode 100644
index 0e4fde5..0000000
--- a/reporter/example/interfaces.py
+++ /dev/null
@@ -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.
- """
-
diff --git a/reporter/interfaces.py b/reporter/interfaces.py
index 30d8767..9eed2be 100644
--- a/reporter/interfaces.py
+++ b/reporter/interfaces.py
@@ -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():
diff --git a/reporter/example/contact.py b/reporter/resultset.py
similarity index 89%
rename from reporter/example/contact.py
rename to reporter/resultset.py
index 963c8fe..46a488b 100644
--- a/reporter/example/contact.py
+++ b/reporter/resultset.py
@@ -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)