Commits

Mike Orr committed 70992cc

Move grid_demo to webhelpers.html; delete obsolete unfinished files.

  • Participants
  • Parent commits fc2f641

Comments (0)

Files changed (6)

 
 tip (development version)
 -------------------------
+* webhelpers.html.grid_demo:
+
+  - Demonstrates ``webhelpers.html.grid``. Run as 
+    "python -m webhelpers.html.grid_demo OUTPUT_DIRECTORY".
+
 * webhelpers.misc:
 
   - New helper ``subclasses_only`` to extract the subclasses of an abstract

File unfinished/grid_demo.py

-"""Demos for webhelpers.html.grid
-
-Run this module as a script::
-
-    python -m webhelpers.html.grid_demo OUTPUT_DIRECTORY
- Dec 16 19:39:54 PST 2009
-"""
-
-import optparse
-import os
-import urllib
-
-from webhelpers.html import *
-from webhelpers.html.grid import Grid
-from webhelpers.html.tags import link_to
-from webhelpers.misc import subclasses_only
-# XXX You may find other helpers in webhelpers.html.tags useful too
-
-#### Global constants ####
-USAGE = "python -m %s OUTPUT_DIRECTORY" % __name__
-
-DESCRIPTION = """\
-Run the demos in this module and put the HTML output in
-OUTPUT_DIRECTORY."""
-
-STYLESHEET = """\
-/******************* tables ****************/
-table.stylized {
-    background-color: #ffffff;
-    border-collapse: separate;
-    border-spacing: 1px;
-    border-bottom: 2px solid #666666;
-    margin: 1px 5px 5px 5px;
-    -moz-border-radius: 5px;
-    -webkit-border-radius: 5px;
-    width: 100%;
-    border-collapse: collapse;
-}
-
-table.stylized caption {
-    color: #ffffff;
-    background-color: #444466;
-    padding: 5px;
-    font-size: 1.3em;
-    font-weight: bold;
-    margin: 5px 0px 0px 0px;
-    -moz-border-radius: 5px;
-    -webkit-border-radius: 5px;
-}
-
-
-
-table.stylized caption a:link,table.stylized caption a:visited{
-    color: #ffffff;
-    text-decoration: none;
-    font-weight: bold;
-}
-
-table.stylized caption a:link,table.stylized caption a:hover{
-    color: #ffcc00;
-    text-decoration: none;
-    font-weight: bold;
-}
-    
-table.stylized thead {
-    background-color: #ffffff;
-}
-
-table.stylized tbody {
-    background-color: #ffffff;
-}
-
-table.stylized tfooter {
-    background-color: #ffffff;
-}
-
-table.stylized th {
-    text-align: center;
-}
-
-table.stylized tr.header {
-    text-align: center;
-}
-
-table.stylized tr.header td, table.stylized th {
-    text-align: center;
-    color: #ffffff;
-    background-color: #444466;
-}
-
-table.stylized td {
-    padding: 5px 5px 5px 5px;
-    border: 1px solid #dcdcdc;
-}
-
-
-table.stylized tr.odd td {
-    border-top: 1px solid #999 !important;
-    background-color: #ffffff;
-}
-
-table.stylized tr.even td {
-    border-top: 1px solid #999 !important;
-    background-color: #f6f6f6;
-}
-
-table.stylized .no {
-    width: 30px;
-}
-
-table.stylized td.ordering.dsc {
-    background-color: #666666;
-    padding-right: 20px;
-}
-
-table.stylized td.ordering.asc {
-    background-color: #666666;
-    padding-right: 20px;
-}
-
-table.stylized td.ordering.dsc .marker {
-    height: 20px;
-    width: 20px;
-    display: block;
-    float: right;
-    margin: 0px -18px;
-}
-
-table.stylized td.ordering.asc .marker {
-    height: 20px;
-    width: 20px;
-    display: block;
-    float: right;
-    margin: 0px -18px;
-}
-
-table.stylized .header a:link,table.stylized .header a:visited {
-    color: #ffffff;
-    text-decoration: none;
-    font-weight: bold;
-}
-
-table.stylized td.ordering a:link,table.stylized td.ordering a:visited {
-    color: #ffcc00;
-    text-decoration: none;
-    font-weight: bold;
-}
-"""
-
-HTML_TEMPLATE = literal("""\
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
-<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
-    <head>
-        <title>%(title)s</title>
-        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
-        <link rel="stylesheet" type="text/css" href="demo.css" />
-    </head>
-    <body>
-        <h1>%(title)s</h1>
-
-        <table class="stylized">
-%(grid)s
-        </table>
-
-        <p>%(description)s</p>
-    </body>
-</html>
-""")
-# XXX There should be helpers to create a basic HTML file.
-
-test_data = [
-             {"group_name": "foo", "options": "lalala", "id":1},
-             {"group_name": "foo2", "options": "lalala2", "id":2},
-             {"group_name": "foo3", "options": "lalala3", "id":3},
-             {"group_name": "foo4", "options": "lalala4", "id":4},
-             ]
-
-#### Demo base class ####
-class _DemoBase(object):
-    title = None
-    description = None
-
-    def get_grid(): 
-        raise NotImplementedError("subclass responsibility")
-
-
-#### Demo classes ###
-class BasicDemo(_DemoBase):
-    name = "Tickets"
-    description = """\
-This table shows a basic grid."""
-
-    def get_grid(self):
-        """
-        basic demo
-        """
-        
-        g = Grid(test_data, columns=["_numbered","group_name","options"])
-        return g
-
-#### Demo classes ###
-class CustomColumnDemo(_DemoBase):
-    name = "CustomColumn"
-    description = """\
-This table shows a grid with a customized column and header label."""
-
-    def get_grid(self):
-        """
-        let's override how rows look like
-        subject is link
-        categories and status hold text based on param of item text , the
-        translations are dicts holding translation strings correlated with
-        integers from db, in this example
-        """
-        def options_td(col_num, i, item):
-            # XXX This module can't depend on 'app_globals' or 'url' or
-            # external data. Define data within this method or class or
-            # in a base class.
-            # Could use HTML.a() instead of link_to().
-            u = url("/tickets/view", ticket_id=item["id"])
-            a = link_to(item["options"], u)
-            return HTML.td(a)
-        
-        g = Grid(test_data, columns=["_numbered","group_name","options"])
-        g.labels = {
-            "options":'FOOBAAR'
-                    }
-        g.column_formats = {
-            "options": options_td,
-            }
-        return g
-
-demos = subclasses_only(_DemoBase, globals())
-
-#demos = [BasicDemo, CustomColumnDemo]
-
-#### Utility functions ####
-def url(urlpath, **params):
-    # This should be a helper and I think it's defined somewhere but I
-    # can't think of where.
-    return urlpath + "?" + urllib.urlencode(params)
-
-def write_file(dir, filename, content):
-    print "... writing '%s'" % filename
-    path = os.path.join(dir, filename)
-    f = open(path, "w")
-    f.write(content)
-    f.close()
-
-#### Main routine ####
-def main():
-    parser = optparse.OptionParser(usage=USAGE, description=DESCRIPTION)
-    opts, args = parser.parse_args()
-    if len(args) != 1:
-        parser.error("wrong number of command-line arguments")
-    dir = args[0]
-    if not os.path.exists(dir):
-        os.makedirs(dir)
-    print "Putting output in directory '%s'" % dir
-    write_file(dir, "demo.css", STYLESHEET)
-    for class_ in demos:
-        d = class_()
-        name = d.name or d.__class__.__name__
-        filename = name + ".html"
-        dic = {
-            "title": d.name or d.__class__.__name__.lower(),
-            "description": d.description,
-            "grid": d.get_grid(),
-            }
-        html = HTML_TEMPLATE % dic
-        write_file(dir, filename, html)
-
-if __name__ == "__main__":  main()

File unfinished/grid_notes.txt

-Grid integration plan for WebHelpers
-====================================
-
-The main problem with table generators is that different people want different
-kinds of tables, and you want to try to accommodate them as much as possible,
-without making the simple case too cumbersome.  I'd suggest putting the
-row-number feature in a subclass because many tables won't need it.  
-
-I'd also suggest a subclass or option for a horizontal table: one with the
-headers in the left row.  These are often two-column tables, with the labels
-implied by the first column in the data.  E.g., dumping a dict.
-
-Generate all HTML using webhelpers.html.builder (examples in
-webhelpers.html.tags). This will also mark the HTML as a preformatted literal,
-so Mako's "|n" filter will no longer be necessary.
-
-Replace .render method with .__str__ .  This will make it automatically render
-when stringified, as Mako does with ${my_grid}.
-
-Write complete module docstring with usage and tests.  (See examples in
-webhelpers.html.tags.) Document that this generates only <tr> and below, not
-<table> or <call> etc.
-
-There doesn't seem to be much use for ``*args`` and ``**kwargs`` since you
-accept a small number of arguments with fixed meanings.  I would replace those
-with positional args, with default values for those that are optional.
-'columns' looks like it should be the second arg and required.  Does
-``.__make_header_columns`` work if 'columns' is missing?
-
-Using methods to generate the header columns and regular columns looks
-interesting; I haven't seen another table class do that, but it may make it
-more flexible for subclassing.  Perhaps even more flexible would be a hook
-method that returns:
-    {tr_attributes}, [ (is_th, {th_or_td_attributes}, cell_content) ]
-This might be general enough to support all kinds of tables.
-
-Double-underscore method names are unnecessary, because this is unlikely to be
-subclassed except to customize the formatting, and the subclass would not have
-conflicting names.
-
-I don't understand the ordering code, so I'm not sure what it's doing.  
-
-'labels' is ambiguous: is it a column header, form element <label>, row or cell
-label, etc?  Consider 'header' instead.
-
-Interesting that ``.labels`` is a dict rather than a list of headers.  I
-suppose that makes it easier to move columns around.
-
-
-Ergos's original comments from ticket
-=====================================
-
-http://bitbucket.org/bbangert/webhelpers/issue/3/table-from-list-helper
-
-Im,a beginner programmer in python so this may need some improving ;-)
-
-what this class can do:
-
-* ordering support for columns with get params
-* customizable row and column rendering via lambdas, support for adding new columns that dont exist in passed lists like row with links to perform actions,
-* any default column rendering style can be overwritten with something custom
-* rows can be overwritten so user can create something like <tr>columns_row</tr><tr>some_other_info</tr>
-* builtin support for even/odd class styling of rows
-* auto generation of nice headers from keys of sa rows, so something_label becoms Something Label
-* headers have nice styling support with smart class usage, for both ordered and unordered fields
-* support for overwriting any header with something else
-* support to specify what columns are rendered and in what order by columns argument
-* every custom row or column markup is specified by lambda/function that returns formattable string 
-
-the simpliest example usage for mako:
-
-<%
-from webreactor.lib.grid import Grid
-news_grid = Grid(c.news_page,columns=['title','date_of_creation'])
-%>
-
-<table class="stylized"> ${news_grid.render()|n} </table>
-
-more complex examples:
-
-<%
-from webreactor.lib.grid import Grid
-news_grid = Grid(c.news_page,columns=['title','date_of_creation','actions'])
-news_grid.exclude_ordering = news_grid.columns
-news_grid.label = {'title':'Some other title'}
-news_grid.format = {
-'actions':lambda i,item: '<td><a href="%s"><span class="icon newsUpdate"></span></a></td>' % (url())
-}
-%>
-
-<table class="stylized"> ${news_grid.render()|n} </table>
-

File unfinished/grid_screenshot.png

Removed
Old image

File unfinished/js_obfuscate.py

-# XXX TODO: Convert js_obfuscate() to use webhelpers.html .
-# The other functions are just dependencies.
-
-def js_obfuscate(data):
-    """Obfuscate data in a Javascript tag.
-    
-    Example::
-        
-        >>> js_obfuscate("<input type='hidden' name='check' value='valid' />")
-        '<script type="text/javascript">\\n//<![CDATA[\\neval(unescape(\\'%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%69%6e%70%75%74%20%74%79%70%65%3d%27%68%69%64%64%65%6e%27%20%6e%61%6d%65%3d%27%63%68%65%63%6b%27%20%76%61%6c%75%65%3d%27%76%61%6c%69%64%27%20%2f%3e%27%29%3b\\'))\\n//]]>\\n</script>'
-        
-    """
-    tmp = "document.write('%s');" % data
-    string = ''.join(['%%%x' % ord(x) for x in tmp])
-    return javascript_tag("eval(unescape('%s'))" % string)
-
-def javascript_tag(content, **html_options):
-    """
-    Return a JavaScript tag with the ``content`` inside.
-    
-    Example::
-    
-        >>> javascript_tag("alert('All is good')")
-        '<script type="text/javascript">\\n//<![CDATA[\\nalert(\\'All is good\\')\\n//]]>\\n</script>'
-    """
-    return content_tag("script", javascript_cdata_section(content), type="text/javascript",
-                       **html_options)
-
-def javascript_cdata_section(content):
-    return "\n//%s\n" % cdata_section("\n%s\n//" % content)
-
-def content_tag(name, content, **options):
-    """
-    Create a tag with content.
-    
-    Takes the same keyword args as ``tag``.
-    
-    Examples::
-    
-        >>> content_tag("p", "Hello world!")
-        '<p>Hello world!</p>'
-        >>> content_tag("div", content_tag("p", "Hello world!"), class_="strong")
-        '<div class="strong"><p>Hello world!</p></div>'
-        
-    """
-    if content is None:
-        content = ''
-    tag = '<%s%s>%s</%s>' % (name, (options and tag_options(**options)) or '', content, name)
-    return tag
-
-def cdata_section(content):
-    """
-    Return a CDATA section with the given ``content``.
-    
-    CDATA sections are used to escape blocks of text containing 
-    characters which would otherwise be recognized as markup. CDATA 
-    sections begin with the string ``<![CDATA[`` and end with (and may 
-    not contain) the string ``]]>``. 
-    
-    """
-    if content is None:
-        content = ''
-    return "<![CDATA[%s]]>" % content
-
-def escape_once(html):
-    """Escape a given string without affecting existing escaped entities.
-
-    >>> escape_once("1 < 2 &amp; 3")
-    '1 &lt; 2 &amp; 3'
-    
-    """
-    return fix_double_escape(html_escape(html))
-

File webhelpers/html/grid_demo.py

+"""Demos for webhelpers.html.grid
+
+Run this module as a script::
+
+    python -m webhelpers.html.grid_demo OUTPUT_DIRECTORY
+ Dec 16 19:39:54 PST 2009
+"""
+
+import optparse
+import os
+import urllib
+
+from webhelpers.html import *
+from webhelpers.html.grid import Grid
+from webhelpers.html.tags import link_to
+from webhelpers.misc import subclasses_only
+# XXX You may find other helpers in webhelpers.html.tags useful too
+
+#### Global constants ####
+USAGE = "python -m %s OUTPUT_DIRECTORY" % __name__
+
+DESCRIPTION = """\
+Run the demos in this module and put the HTML output in
+OUTPUT_DIRECTORY."""
+
+STYLESHEET = """\
+/******************* tables ****************/
+table.stylized {
+    background-color: #ffffff;
+    border-collapse: separate;
+    border-spacing: 1px;
+    border-bottom: 2px solid #666666;
+    margin: 1px 5px 5px 5px;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+    width: 100%;
+    border-collapse: collapse;
+}
+
+table.stylized caption {
+    color: #ffffff;
+    background-color: #444466;
+    padding: 5px;
+    font-size: 1.3em;
+    font-weight: bold;
+    margin: 5px 0px 0px 0px;
+    -moz-border-radius: 5px;
+    -webkit-border-radius: 5px;
+}
+
+
+
+table.stylized caption a:link,table.stylized caption a:visited{
+    color: #ffffff;
+    text-decoration: none;
+    font-weight: bold;
+}
+
+table.stylized caption a:link,table.stylized caption a:hover{
+    color: #ffcc00;
+    text-decoration: none;
+    font-weight: bold;
+}
+    
+table.stylized thead {
+    background-color: #ffffff;
+}
+
+table.stylized tbody {
+    background-color: #ffffff;
+}
+
+table.stylized tfooter {
+    background-color: #ffffff;
+}
+
+table.stylized th {
+    text-align: center;
+}
+
+table.stylized tr.header {
+    text-align: center;
+}
+
+table.stylized tr.header td, table.stylized th {
+    text-align: center;
+    color: #ffffff;
+    background-color: #444466;
+}
+
+table.stylized td {
+    padding: 5px 5px 5px 5px;
+    border: 1px solid #dcdcdc;
+}
+
+
+table.stylized tr.odd td {
+    border-top: 1px solid #999 !important;
+    background-color: #ffffff;
+}
+
+table.stylized tr.even td {
+    border-top: 1px solid #999 !important;
+    background-color: #f6f6f6;
+}
+
+table.stylized .no {
+    width: 30px;
+}
+
+table.stylized td.ordering.dsc {
+    background-color: #666666;
+    padding-right: 20px;
+}
+
+table.stylized td.ordering.asc {
+    background-color: #666666;
+    padding-right: 20px;
+}
+
+table.stylized td.ordering.dsc .marker {
+    height: 20px;
+    width: 20px;
+    display: block;
+    float: right;
+    margin: 0px -18px;
+}
+
+table.stylized td.ordering.asc .marker {
+    height: 20px;
+    width: 20px;
+    display: block;
+    float: right;
+    margin: 0px -18px;
+}
+
+table.stylized .header a:link,table.stylized .header a:visited {
+    color: #ffffff;
+    text-decoration: none;
+    font-weight: bold;
+}
+
+table.stylized td.ordering a:link,table.stylized td.ordering a:visited {
+    color: #ffcc00;
+    text-decoration: none;
+    font-weight: bold;
+}
+"""
+
+HTML_TEMPLATE = literal("""\
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+    <head>
+        <title>%(title)s</title>
+        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
+        <link rel="stylesheet" type="text/css" href="demo.css" />
+    </head>
+    <body>
+        <h1>%(title)s</h1>
+
+        <table class="stylized">
+%(grid)s
+        </table>
+
+        <p>%(description)s</p>
+    </body>
+</html>
+""")
+# XXX There should be helpers to create a basic HTML file.
+
+test_data = [
+             {"group_name": "foo", "options": "lalala", "id":1},
+             {"group_name": "foo2", "options": "lalala2", "id":2},
+             {"group_name": "foo3", "options": "lalala3", "id":3},
+             {"group_name": "foo4", "options": "lalala4", "id":4},
+             ]
+
+#### Demo base class ####
+class _DemoBase(object):
+    title = None
+    description = None
+
+    def get_grid(): 
+        raise NotImplementedError("subclass responsibility")
+
+
+#### Demo classes ###
+class BasicDemo(_DemoBase):
+    name = "Tickets"
+    description = """\
+This table shows a basic grid."""
+
+    def get_grid(self):
+        """
+        basic demo
+        """
+        
+        g = Grid(test_data, columns=["_numbered","group_name","options"])
+        return g
+
+#### Demo classes ###
+class CustomColumnDemo(_DemoBase):
+    name = "CustomColumn"
+    description = """\
+This table shows a grid with a customized column and header label."""
+
+    def get_grid(self):
+        """
+        let's override how rows look like
+        subject is link
+        categories and status hold text based on param of item text , the
+        translations are dicts holding translation strings correlated with
+        integers from db, in this example
+        """
+        def options_td(col_num, i, item):
+            # XXX This module can't depend on 'app_globals' or 'url' or
+            # external data. Define data within this method or class or
+            # in a base class.
+            # Could use HTML.a() instead of link_to().
+            u = url("/tickets/view", ticket_id=item["id"])
+            a = link_to(item["options"], u)
+            return HTML.td(a)
+        
+        g = Grid(test_data, columns=["_numbered","group_name","options"])
+        g.labels = {
+            "options":'FOOBAAR'
+                    }
+        g.column_formats = {
+            "options": options_td,
+            }
+        return g
+
+demos = subclasses_only(_DemoBase, globals())
+
+#demos = [BasicDemo, CustomColumnDemo]
+
+#### Utility functions ####
+def url(urlpath, **params):
+    # This should be a helper and I think it's defined somewhere but I
+    # can't think of where.
+    return urlpath + "?" + urllib.urlencode(params)
+
+def write_file(dir, filename, content):
+    print "... writing '%s'" % filename
+    path = os.path.join(dir, filename)
+    f = open(path, "w")
+    f.write(content)
+    f.close()
+
+#### Main routine ####
+def main():
+    parser = optparse.OptionParser(usage=USAGE, description=DESCRIPTION)
+    opts, args = parser.parse_args()
+    if len(args) != 1:
+        parser.error("wrong number of command-line arguments")
+    dir = args[0]
+    if not os.path.exists(dir):
+        os.makedirs(dir)
+    print "Putting output in directory '%s'" % dir
+    write_file(dir, "demo.css", STYLESHEET)
+    for class_ in demos:
+        d = class_()
+        name = d.name or d.__class__.__name__
+        filename = name + ".html"
+        dic = {
+            "title": d.name or d.__class__.__name__.lower(),
+            "description": d.description,
+            "grid": d.get_grid(),
+            }
+        html = HTML_TEMPLATE % dic
+        write_file(dir, filename, html)
+
+if __name__ == "__main__":  main()