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)