SVN: r21312 - in trunk/quixote: . form

Andrew Kuchling <akuchlin-fVcApmY9cLvQ3/1i3zOLAti2O/[email protected]> Wed, 09 Apr 2003 14:33:56 -0400
Newsgroups gmane.comp.web.quixote.cvs
Message-ID <[email protected]>
Author: akuchlin
Date: 2003-04-09 14:33:54 -0400 (Wed, 09 Apr 2003)
New Revision: 21312

Modified:
   trunk/quixote/CHANGES
   trunk/quixote/form/form.ptl
Log:
Translate the quixote.form.form module from PTL into straight Python.

Please inspect to be sure that I didn't introduce any semantic changes.
My next checkin will simply move form.ptl to form.py.


Modified: trunk/quixote/CHANGES
==============================================================================
--- trunk/quixote/CHANGES	(original)
+++ trunk/quixote/CHANGES	2003-04-09 14:33:56.000000000 -0400
@@ -1,9 +1,14 @@
-0.6?? (?? Mar 2003):
+0.6?? (?? Apr 2003):
 
   * Rename _q_getname() to _q_lookup().  The name '_q_getname' is still
     supported, but will log a warning whenever it's encountered.
     This change will require users to modify their applications.
 
+  * quixote.form.form has been translated from PTL to Python, meaning 
+    that you can now use the form framework without enabling PTL.
+    (Original suggestion by Jim Dukarm, who also provided a patch 
+    that underwent considerable tweaking.)
+
   * Fix generation of temporary filenames in upload.py: filename
     collisions should be impossible now.
 

Modified: trunk/quixote/form/form.ptl
==============================================================================
--- trunk/quixote/form/form.ptl	(original)
+++ trunk/quixote/form/form.ptl	2003-04-09 14:33:56.000000000 -0400
@@ -8,7 +8,7 @@
 
 from types import StringType
 from quixote import get_session, get_publisher
-from quixote.html import url_quote, htmltag, htmltext, nl2br
+from quixote.html import url_quote, htmltag, htmltext, nl2br, htmlescape
 from quixote.form.widget import FormValueError, HiddenWidget
 
 
@@ -26,6 +26,13 @@
 </script>
 ''')
 
+def _join (seq):
+    s = ""
+    for item in seq:
+        if item is None:
+            continue
+        s = s + htmlescape(item)
+    return s
 
 class Form:
     """
@@ -139,100 +146,136 @@
     # combine text and widgets in a 1-D stream of HTML, or in a 2-D web
     # page (depending on your level of abstraction).
 
-    def render [html] (self, request, action_url):
+    def render (self, request, action_url):
         # render(request : HTTPRequest,
         #           action_url : string)
         #    -> HTML text
         #
         # Render a form as HTML.
         assert type(action_url) in (StringType, htmltext)
-        self._render_start(request, action_url, self.enctype, self.method)
-        self._render_body(request)
-        self._render_finish(request)
-
-    def _render_start [html] (self, request, action,
-                              enctype=None, method='post', name=None):
-        htmltag('form', enctype=enctype, method=method,
-                action=action, name=name)
-        "\n"
-        self._render_hidden_widgets(request)
-
-    def _render_finish [html] (self, request):
-        '</form>\n'
-        self._render_javascript(request)
-
-    def _render_sep [html] (self, text, line=1):
-        ('<tr><td colspan="3">%s<strong><big>%s</big></strong></td></tr>\n' %
-         (line and '<hr>' or '', text))
+        parts = [
+            self._render_start(request, action_url,
+                               enctype=self.enctype, method=self.method),
+            self._render_body(request),
+            self._render_finish(request),
+            ]
+
+        return _join(parts)
+
+    def _render_start (self, request, action,
+                      enctype=None, method='post', name=None):
+        parts = [
+            htmltag('form', enctype=enctype, method=method,
+                    action=action, name=name),
+            self._render_hidden_widgets(request),
+            ]
+        return _join(parts)
+
+    def _render_finish (self, request):
+        parts = [
+            htmltext('</form>'),
+            self._render_javascript(request),
+            ]
+        return _join(parts)
+
+    def _render_sep (self, text, line=1):
+        return (
+            htmltext('<tr><td colspan="3">%s<strong><big>%s</big></strong></td></tr>') %
+            (line and htmltext('<hr>') or '', text))
 
-    def _render_error [html] (self, error):
+    def _render_error (self, error):
         if error:
-            '<font color="red">' + nl2br(error) + '</font><br />\n'
+            return (htmltext('<font color="red">%s</font><br />')
+                    % str(nl2br(error)))
+        else:
+            return ''
 
-    def _render_hint [html] (self, hint):
+    def _render_hint (self, hint):
         if hint:
-            '<em>' + hint + '</em>\n'
+            return htmltext('<em>%s</em>') % hint
+        else:
+            return ''
 
-    def _render_widget_row [html] (self, request, widget):
+    def _render_widget_row (self, request, widget):
         if widget.widget_type == 'hidden':
-            return
+            return ''
         title = self.title[widget.name] or ''
         if self.required.get(widget.name):
-            title = title + '&nbsp;*'
-        '<tr>'
-        '<th colspan="3" align="left">'
-        title
-        '</th>\n'
-        '</tr>'
-        '<tr>'
-        '<td>&nbsp;&nbsp;</td>'
-        '<td>'
-        widget.render(request)
-        '</td>\n'
-        '<td>'
-        self._render_error(self.error.get(widget.name))
-        self._render_hint(self.hint.get(widget.name))
-        '</td>\n'
-        '</tr>\n'
+            title = title + htmltext('&nbsp;*')
+        parts = [
+            htmltext('<tr>'),
+            htmltext('<th colspan="3" align="left">'),
+            title,
+            htmltext('</th>'),
+            htmltext('</tr>'),
+            htmltext('<tr>'),
+            htmltext('<td>&nbsp;&nbsp;</td>'),
+            htmltext('<td>'),
+            widget.render(request),
+            htmltext('</td>'),
+            htmltext('<td>'),
+            self._render_error(self.error.get(widget.name)),
+            self._render_hint(self.hint.get(widget.name)),
+            htmltext('</td>'),
+            htmltext('</tr>'),
+            ]
+        print parts
+        return _join(parts)
 
-    def _render_hidden_widgets [html] (self, request):
+    def _render_hidden_widgets (self, request):
+        parts = []
         for widget in self.widget_order:
             if widget.widget_type == 'hidden':
-                widget.render(request)
-                self._render_error(self.error.get(widget.name))
-                '\n'
+                parts += [
+                    widget.render(request),
+                    self._render_error(self.error.get(widget.name)),
+                    ]
+        return _join(parts)
 
-    def _render_submit_buttons [html] (self, request, ncols=3):
-        '<tr><td colspan="%d">\n' % ncols
+    def _render_submit_buttons (self, request, ncols=3):
+        parts = [htmltext('<tr><td colspan="%d">\n') % ncols]
         for button in self.submit_buttons:
-            button.render(request)
-            '\n'
-        '</td></tr>'
+            parts.append(button.render(request))
+        parts.append(htmltext('</td></tr>'))
+        return _join(parts)
 
-    def _render_visible_widgets [html] (self, request):
+    def _render_visible_widgets (self, request):
+        parts = []
         for widget in self.widget_order:
-            self._render_widget_row(request, widget)
+            parts.append(self._render_widget_row(request, widget))
+        return _join(parts)
 
-    def _render_error_notice [html] (self, request):
+    def _render_error_notice (self, request):
+        parts = []
         if self.error:
-            '<tr><td colspan="3">'
-            '<font color="red"><strong>Warning:</strong></font> '
-            'there were errors processing your form.  See below for details.'
-            '</td></tr>\n'
+            parts += [
+                htmltext('<tr><td colspan="3">'),
+                htmltext('<font color="red"><strong>Warning:</strong></font> '),
+                htmltext('there were errors processing your form.  See below for details.'),
+                htmltext('</td></tr>'),
+                ]
+        return _join(parts)
 
-    def _render_required_notice [html] (self, request):
+    def _render_required_notice (self, request):
+        parts = []
         if filter(None, self.required.values()):
-            '<tr><td colspan="3">'
-            '<b>*</b> = <em>required field</em>'
-            '</td></tr>\n'
-
-    def _render_body [html] (self, request):
-        '<table>'
-        self._render_error_notice(request)
-        self._render_required_notice(request)
-        self._render_visible_widgets(request)
-        self._render_submit_buttons(request)
-        '</table>'
+            parts += [
+                htmltext('<tr><td colspan="3">'),
+                htmltext('<b>*</b> = <em>required field</em>'),
+                htmltext('</td></tr>'),
+                ]
+        return _join(parts)
+
+    def _render_body (self, request):
+        parts = [
+            htmltext('<table>'),
+            self._render_error_notice(request),
+            self._render_required_notice(request),
+            self._render_visible_widgets(request),
+            self._render_submit_buttons(request),
+            htmltext('</table>'),
+            ]
+        return _join(parts)
 
     def _render_javascript (self, request):
         """Render javacript code for the form, if any.