[Checkins] SVN: zc.table/branches/srichter-enhancements/ For review: A few enhancements to formatters. Ideally they should all be

Stephan Richter srichter at cosmos.phy.tufts.edu
Mon Aug 14 17:42:43 EDT 2006


Log message for revision 69495:
  For review: A few enhancements to formatters. Ideally they should all be 
  combinable, which they are not. If people like those changes I will 
  refactor zc.table formatters to be more flexible and support those 
  features.
  
  

Changed:
  A   zc.table/branches/srichter-enhancements/extable.py
  A   zc.table/branches/srichter-enhancements/extable.txt
  U   zc.table/branches/srichter-enhancements/tests.py

-=-
Added: zc.table/branches/srichter-enhancements/extable.py
===================================================================
--- zc.table/branches/srichter-enhancements/extable.py	2006-08-14 19:57:16 UTC (rev 69494)
+++ zc.table/branches/srichter-enhancements/extable.py	2006-08-14 21:42:43 UTC (rev 69495)
@@ -0,0 +1,82 @@
+##############################################################################
+#
+# Copyright (c) 2004 Zope Corporation and Contributors.
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+##############################################################################
+"""Table formatting and configuration
+
+$Id$
+"""
+from zc.table import table
+from xml.sax.saxutils import quoteattr
+
+class SelectedItemFormatterMixin(table.AlternatingRowFormatterMixin,
+                                 table.Formatter):
+    """A formatter that allows selecting a single item."""
+
+    # Simply set the item that is being selected
+    selectedItem = None
+
+    def renderRow(self, item):
+        self.row += 1
+        klass = self.cssClasses.get('tr', '')
+        if klass:
+            klass += ' '
+        else:
+            klass += self.row_classes[self.row % 2]
+
+        if item == self.selectedItem:
+            klass += ' selected'
+
+        return '  <tr class=%s>\n%s  </tr>\n' % (
+            quoteattr(klass), self.renderCells(item))
+
+
+class CSSColumnFormatterMixin(object):
+    """A formatter that allows you to specify a CSS class per column."""
+
+    columnCSS = None
+
+    def __init__(self, *args, **kw):
+        super(CSSColumnFormatterMixin, self).__init__(*args, **kw)
+        self.columnCSS = {}
+
+    def renderHeader(self, column):
+        klass = self.cssClasses.get('tr', '')
+        if column.name in self.columnCSS:
+            klass += klass and ' ' or '' + self.columnCSS[column.name]
+        return '      <th class=%s>\n        %s\n      </th>\n' % (
+            quoteattr(klass), self.getHeader(column))
+
+    def renderCell(self, item, column):
+        klass = self.cssClasses.get('tr', '')
+        if column.name in self.columnCSS:
+            klass += klass and ' ' or '' + self.columnCSS[column.name]
+        return '    <td class=%s>\n      %s\n    </td>\n' % (
+            quoteattr(klass), self.getCell(item, column))
+
+
+class WidthSpecificationFormatterMixin(object):
+    """A formatter that allows specifying the width of each column."""
+
+    # If set, this is expected to be a sequence of width integers
+    columnWidths = None
+
+    def renderHeader(self, column):
+        width = ''
+        if self.columnWidths:
+            idx = list(self.visible_columns).index(column)
+            width = ' width="%i"' %self.columnWidths[idx]
+
+        return '      <th%s%s>\n        %s\n      </th>\n' % (
+            self._getCSSClass('th'), width, self.getHeader(column))
+
+


Property changes on: zc.table/branches/srichter-enhancements/extable.py
___________________________________________________________________
Name: svn:keywords
   + Id

Added: zc.table/branches/srichter-enhancements/extable.txt
===================================================================
--- zc.table/branches/srichter-enhancements/extable.txt	2006-08-14 19:57:16 UTC (rev 69494)
+++ zc.table/branches/srichter-enhancements/extable.txt	2006-08-14 21:42:43 UTC (rev 69495)
@@ -0,0 +1,419 @@
+==========================
+Table Formatter Extensions
+==========================
+
+This doctest documents the table formatter extensions provided in the
+``extable`` module. Here is a data set that we would like to show:
+
+  >>> class DataItem(object):
+  ...     def __init__(self, numeric, roman, word):
+  ...         self.numeric = numeric
+  ...         self.roman = roman
+  ...         self.word = word
+
+  >>> items = [
+  ...     DataItem('1', 'I',   'one'),
+  ...     DataItem('2', 'II',  'two'),
+  ...     DataItem('3', 'III', 'three'),
+  ... ]
+
+We also need some columns:
+
+  >>> from zc.table import column
+  >>> columns = [
+  ...     column.GetterColumn(u'Numeric', lambda i,f: i.numeric, name='num'),
+  ...     column.GetterColumn(u'Roman', lambda i,f: i.roman, name='roman'),
+  ...     column.GetterColumn(u'Word', lambda i,f: i.word, name='word'),
+  ... ]
+
+Finally, let's set up some other helpers:
+
+  >>> import zope.publisher.browser
+  >>> request = zope.publisher.browser.TestRequest()
+  >>> context = None
+
+
+Selected Item Formatter
+-----------------------
+
+The selected item formatter allows you to specify a single item of values that
+is to be marked as selected. It simply adds the CSS class "selected" to the
+appropriate ``<tr>`` element.
+
+  >>> from zc.table import extable
+  >>> formatter = extable.SelectedItemFormatterMixin(
+  ...     context, request, items, columns=columns)
+
+  >>> print formatter()
+  <BLANKLINE>
+  <table>
+    <thead>
+      <tr>
+        <th>
+          Numeric
+        </th>
+        <th>
+          Roman
+        </th>
+        <th>
+          Word
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr class="odd">
+      <td>
+        1
+      </td>
+      <td>
+        I
+      </td>
+      <td>
+        one
+      </td>
+    </tr>
+    <tr class="even">
+      <td>
+        2
+      </td>
+      <td>
+        II
+      </td>
+      <td>
+        two
+      </td>
+    </tr>
+    <tr class="odd">
+      <td>
+        3
+      </td>
+      <td>
+        III
+      </td>
+      <td>
+        three
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <BLANKLINE>
+
+Let's now select an item:
+
+  >>> formatter.selectedItem = items[1]
+  >>> print formatter()
+  <BLANKLINE>
+  <table>
+    <thead>
+      <tr>
+        <th>
+          Numeric
+        </th>
+        <th>
+          Roman
+        </th>
+        <th>
+          Word
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr class="odd">
+      <td>
+        1
+      </td>
+      <td>
+        I
+      </td>
+      <td>
+        one
+      </td>
+    </tr>
+    <tr class="even selected">
+      <td>
+        2
+      </td>
+      <td>
+        II
+      </td>
+      <td>
+        two
+      </td>
+    </tr>
+    <tr class="odd">
+      <td>
+        3
+      </td>
+      <td>
+        III
+      </td>
+      <td>
+        three
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <BLANKLINE>
+
+Possible Improvement: Allow multiple items to be selected by making the
+attribute ``selectedItem`` a sequence and be called ``selectedItems``.
+
+
+CSS Column Formatter
+--------------------
+
+The standard formatter provides no facilities to select columns, but selecting
+columns is interesting in many ways, for example, when you sort a particular
+column. You can also use this base class to simulate alternating *columns*.
+
+  >>> from zc.table import table
+
+  >>> class CSSColumnFormatter(extable.CSSColumnFormatterMixin,
+  ...                          table.Formatter):
+  ...     pass
+
+  >>> formatter = CSSColumnFormatter(context, request, items, columns=columns)
+  >>> print formatter()
+  <BLANKLINE>
+  <table>
+    <thead>
+      <tr>
+        <th class="">
+          Numeric
+        </th>
+        <th class="">
+          Roman
+        </th>
+        <th class="">
+          Word
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td class="">
+        1
+      </td>
+      <td class="">
+        I
+      </td>
+      <td class="">
+        one
+      </td>
+    </tr>
+    <tr>
+      <td class="">
+        2
+      </td>
+      <td class="">
+        II
+      </td>
+      <td class="">
+        two
+      </td>
+    </tr>
+    <tr>
+      <td class="">
+        3
+      </td>
+      <td class="">
+        III
+      </td>
+      <td class="">
+        three
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <BLANKLINE>
+
+To selection a CSS class for a particular column, you simply fill out the
+formatter's ``columnCSS`` dictionary. The key is the column name and the value
+the entry for the CSS class.
+
+  >>> formatter.columnCSS['roman'] = 'selected'
+  >>> print formatter()
+  <BLANKLINE>
+  <table>
+    <thead>
+      <tr>
+        <th class="">
+          Numeric
+        </th>
+        <th class="selected">
+          Roman
+        </th>
+        <th class="">
+          Word
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td class="">
+        1
+      </td>
+      <td class="selected">
+        I
+      </td>
+      <td class="">
+        one
+      </td>
+    </tr>
+    <tr>
+      <td class="">
+        2
+      </td>
+      <td class="selected">
+        II
+      </td>
+      <td class="">
+        two
+      </td>
+    </tr>
+    <tr>
+      <td class="">
+        3
+      </td>
+      <td class="selected">
+        III
+      </td>
+      <td class="">
+        three
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <BLANKLINE>
+
+
+Possible Improvement: Make the values of the ``cssColumn`` attribute a list,
+so that applications can rely on simply appending to the list.
+
+
+Width Specification Formatter
+-----------------------------
+
+One of the simplest missing features was the support for specifying the column
+width.
+
+  >>> class WidthSpecificationFormatter(
+  ...     extable.WidthSpecificationFormatterMixin, table.Formatter):
+  ...     pass
+
+  >>> formatter = WidthSpecificationFormatter(
+  ...     context, request, items, columns=columns)
+  >>> print formatter()
+  <BLANKLINE>
+  <table>
+    <thead>
+      <tr>
+        <th>
+          Numeric
+        </th>
+        <th>
+          Roman
+        </th>
+        <th>
+          Word
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td>
+        1
+      </td>
+      <td>
+        I
+      </td>
+      <td>
+        one
+      </td>
+    </tr>
+    <tr>
+      <td>
+        2
+      </td>
+      <td>
+        II
+      </td>
+      <td>
+        two
+      </td>
+    </tr>
+    <tr>
+      <td>
+        3
+      </td>
+      <td>
+        III
+      </td>
+      <td>
+        three
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <BLANKLINE>
+
+To specify the widths of the columns, simply fill out a sequence:
+
+  >>> formatter.columnWidths = [100, 50, 75]
+  >>> print formatter()
+  <BLANKLINE>
+  <table>
+    <thead>
+      <tr>
+        <th width="100">
+          Numeric
+        </th>
+        <th width="50">
+          Roman
+        </th>
+        <th width="75">
+          Word
+        </th>
+      </tr>
+    </thead>
+    <tbody>
+    <tr>
+      <td>
+        1
+      </td>
+      <td>
+        I
+      </td>
+      <td>
+        one
+      </td>
+    </tr>
+    <tr>
+      <td>
+        2
+      </td>
+      <td>
+        II
+      </td>
+      <td>
+        two
+      </td>
+    </tr>
+    <tr>
+      <td>
+        3
+      </td>
+      <td>
+        III
+      </td>
+      <td>
+        three
+      </td>
+    </tr>
+    </tbody>
+  </table>
+  <BLANKLINE>
+
+Possible Improvement: The attribute could be a mapping from column name to
+width, so that it also works when the length of selected columns does not
+equal the length of total columns (which was not a use case of mine).


Property changes on: zc.table/branches/srichter-enhancements/extable.txt
___________________________________________________________________
Name: svn:eol-style
   + native

Modified: zc.table/branches/srichter-enhancements/tests.py
===================================================================
--- zc.table/branches/srichter-enhancements/tests.py	2006-08-14 19:57:16 UTC (rev 69494)
+++ zc.table/branches/srichter-enhancements/tests.py	2006-08-14 21:42:43 UTC (rev 69495)
@@ -40,6 +40,9 @@
 def test_suite():
     from zope.testing import doctest
     return unittest.TestSuite((
+        doctest.DocFileSuite('extable.txt',
+            optionflags=doctest.NORMALIZE_WHITESPACE+doctest.ELLIPSIS,
+            ),
         doctest.DocFileSuite('README.txt',
             optionflags=doctest.NORMALIZE_WHITESPACE+doctest.ELLIPSIS,
             ),



More information about the Checkins mailing list