Code

Exposed the Batch mechanism through the top-level "utils" variable. See the
authorrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 11 Sep 2002 23:54:26 +0000 (23:54 +0000)
committerrichard <richard@57a73879-2fb5-44c3-a270-3262357dd7e2>
Wed, 11 Sep 2002 23:54:26 +0000 (23:54 +0000)
keyword.item template for an example of how it can be used.

git-svn-id: http://svn.roundup-tracker.org/svnroot/roundup/trunk@1142 57a73879-2fb5-44c3-a270-3262357dd7e2

roundup/cgi/ZTUtils/Batch.py
roundup/cgi/client.py
roundup/cgi/templating.py
roundup/templates/classic/html/keyword.item
roundup/templates/classic/html/style.css

index 713d771f47743e0652ca6c560a6ab27c8d536a0e..3dfa9b1a1bd4d1709d683513a1d91ac0659deb2e 100644 (file)
@@ -12,8 +12,8 @@
 ##############################################################################
 __doc__='''Batch class, for iterating over a sequence in batches
 
-$Id: Batch.py,v 1.1 2002-09-05 00:37:09 richard Exp $'''
-__version__='$Revision: 1.1 $'[11:-2]
+$Id: Batch.py,v 1.2 2002-09-11 23:54:26 richard Exp $'''
+__version__='$Revision: 1.2 $'[11:-2]
 
 class LazyPrevBatch:
     def __of__(self, parent):
@@ -84,7 +84,7 @@ class Batch:
             return self._sequence[index + self.end]
         
         if index >= self.length: raise IndexError, index
-        return self._sequence[index+self.first]
+        return self._sequence[index + self.first]
 
     def __len__(self):
         return self.length
index 97342dbd9e097a0d4b9382ffaa271f27dd77aab0..9bbe94e785e481a5b69cab153aeadf5ab0cc56ef 100644 (file)
@@ -1,4 +1,4 @@
-# $Id: client.py,v 1.27 2002-09-10 12:44:42 richard Exp $
+# $Id: client.py,v 1.28 2002-09-11 23:54:25 richard Exp $
 
 __doc__ = """
 WWW request handler (also used in the stand-alone server).
@@ -99,6 +99,11 @@ class Client:
             # someone gave us a non-int debug level, turn it off
             self.debug = 0
 
+        # additional headers to send with the request - must be registered
+        # before the first write
+        self.additional_headers = {}
+        self.response_code = 200
+
     def main(self):
         ''' Process a request.
 
@@ -149,7 +154,9 @@ class Client:
             # the headers, otherwise the headers have been set before the
             # exception was raised
             if url:
-                self.header({'Location': url}, response=302)
+                self.additional_headers['Location'] = url
+                self.response_code = 302
+            self.write('Redirecting to <a href="%s">%s</a>'%(url, url))
         except SendFile, designator:
             self.serve_file(designator)
         except SendStaticFile, file:
@@ -303,13 +310,13 @@ class Client:
 
         # we just want to serve up the file named
         file = self.db.file
-        self.header({'Content-Type': file.get(nodeid, 'type')})
+        self.additional_headers['Content-Type'] = file.get(nodeid, 'type')
         self.write(file.get(nodeid, 'content'))
 
     def serve_static_file(self, file):
         # we just want to serve up the file named
         mt = mimetypes.guess_type(str(file))[0]
-        self.header({'Content-Type': mt})
+        self.additional_headers['Content-Type'] = mt
         self.write(open(os.path.join(self.instance.config.TEMPLATES,
             file)).read())
 
@@ -395,11 +402,14 @@ class Client:
             self.header()
         self.request.wfile.write(content)
 
-    def header(self, headers=None, response=200):
+    def header(self, headers=None, response=None):
         '''Put up the appropriate header.
         '''
         if headers is None:
             headers = {'Content-Type':'text/html'}
+        if response is None:
+            response = self.response_code
+        headers.update(self.additional_headers)
         if not headers.has_key('Content-Type'):
             headers['Content-Type'] = 'text/html'
         self.request.send_response(response)
@@ -433,8 +443,8 @@ class Client:
         # generate the cookie path - make sure it has a trailing '/'
         path = '/'.join((self.env['SCRIPT_NAME'], self.env['TRACKER_NAME'],
             ''))
-        self.header({'Set-Cookie': 'roundup_user_2=%s; expires=%s; Path=%s;'%(
-            self.session, expire, path)})
+        self.additional_headers['Set-Cookie'] = \
+          'roundup_user_2=%s; expires=%s; Path=%s;'%(self.session, expire, path)
 
     def make_user_anonymous(self):
         ''' Make us anonymous
@@ -454,9 +464,8 @@ class Client:
         now = Cookie._getdate()
         path = '/'.join((self.env['SCRIPT_NAME'], self.env['TRACKER_NAME'],
             ''))
-        self.header({'Set-Cookie':
-            'roundup_user_2=deleted; Max-Age=0; expires=%s; Path=%s;'%(now,
-            path)})
+        self.additional_headers['Set-Cookie'] = \
+           'roundup_user_2=deleted; Max-Age=0; expires=%s; Path=%s;'%(now, path)
         self.login()
 
     def opendb(self, user):
@@ -530,8 +539,8 @@ class Client:
         now = Cookie._getdate()
         path = '/'.join((self.env['SCRIPT_NAME'], self.env['TRACKER_NAME'],
             ''))
-        self.header(headers={'Set-Cookie':
-          'roundup_user_2=deleted; Max-Age=0; expires=%s; Path=%s;'%(now, path)})
+        self.additional_headers['Set-Cookie'] = \
+           'roundup_user_2=deleted; Max-Age=0; expires=%s; Path=%s;'%(now, path)
 
         # Let the user know what's going on
         self.ok_message.append(_('You are logged out'))
@@ -578,7 +587,11 @@ class Client:
         self.set_cookie(self.user, password)
 
         # nice message
-        self.ok_message.append(_('You are now registered, welcome!'))
+        message = _('You are now registered, welcome!')
+
+        # redirect to the item's edit page
+        raise Redirect, '%s/%s%s?:ok_message=%s'%(
+            self.base, self.classname, self.userid,  urllib.quote(message))
 
     def registerPermission(self, props):
         ''' Determine whether the user has permission to register
index f1b78b448790ed8da5cf57b7dc7e219f38a89e1b..f9f9c96f212560dd6ede4fe90e65e91c915f109a 100644 (file)
@@ -150,7 +150,8 @@ class RoundupPageTemplate(PageTemplate.PageTemplate):
              'request': request,
              'content': client.content,
              'db': HTMLDatabase(client),
-             'instance': client.instance
+             'instance': client.instance,
+             'utils': TemplatingUtils(client),
         }
         # add in the item if there is one
         if client.nodeid:
@@ -263,7 +264,6 @@ class HTMLClass:
                     value = []
                 else:
                     value = None
-            print (prop, value)
             return htmlklass(self._client, '', prop, item, value)
 
         # no good
@@ -1316,7 +1316,8 @@ class Batch(ZTUtils.Batch):
             if index + self.end < self.first: raise IndexError, index
             return self._sequence[index + self.end]
         
-        if index >= self.length: raise IndexError, index
+        if index >= self.length:
+            raise IndexError, index
 
         # move the last_item along - but only if the fetched index changes
         # (for some reason, index 0 is fetched twice)
@@ -1324,13 +1325,16 @@ class Batch(ZTUtils.Batch):
             self.last_item = self.current_item
             self.last_index = index
 
-        # wrap the return in an HTMLItem
-        if self.classname == 'user':
-            klass = HTMLUser
-        else:
-            klass = HTMLItem
-        self.current_item = klass(self.client, self.classname,
-            self._sequence[index+self.first])
+        item = self._sequence[index + self.first]
+        if not isinstance(item, HTMLItem):
+            # "item" is actually just an id - wrap the return in an HTMLItem
+            if self.classname == 'user':
+                klass = HTMLUser
+            else:
+                klass = HTMLItem
+            item = klass(self.client, self.classname, item)
+
+        self.current_item = item
         return self.current_item
 
     def propchanged(self, property):
@@ -1362,3 +1366,12 @@ class Batch(ZTUtils.Batch):
         self.sequence_length = l = len(self._sequence)
         return l
 
+class TemplatingUtils:
+    ''' Utilities for templating
+    '''
+    def __init__(self, client):
+        self.client = client
+    def Batch(self, classname, l, size, start, end=0, orphan=0, overlap=0):
+        return Batch(self.client, classname, l, size, start, end, orphan,
+            overlap)
+
index 60b3f35e79a8dd8f89bdfbf5064e7c9c15adf227..06c00d1c129e4a151dfcc0b37381ffc0ab8bd19a 100644 (file)
@@ -1,7 +1,20 @@
 <!-- dollarId: keyword.item,v 1.3 2002/05/22 00:32:34 richard Exp dollar-->
 
+<table class="otherinfo">
+<tr><th colspan="4" class="header">Existing Keywords</th></tr>
+<tal:block tal:define="keywords db/keyword/list"
+           tal:repeat="start python:range(0, len(keywords), 4)">
+ <tr tal:define="batch python:utils.Batch('keyword', keywords, 4, start)">
+  <td tal:repeat="keyword batch" tal:content="keyword/name">
+   keyword goes here
+  </td>
+ </tr>
+</tal:block>
+<tr><td colspan="4" style="border-top: 1px solid gray">&nbsp;</td></tr>
+</table>
+
 <p class="help" tal:condition="not:context/id">
Use this form to create a new keyword.
To create a new keyword, enter it below and click "Submit New Entry".
 </p>
 
 <form method="POST" onSubmit="return submit_once()"
index f6477170b28e40ee1460da286e47ae1d104fbd04..bbb7f1838e6c624472ecd0db5355d0cf9d75026b 100644 (file)
@@ -240,27 +240,6 @@ table.history td {
   empty-cells: show;
 }
 
-/* style for "other" displays */
-table.otherinfo {
-  border-spacing: 0px;
-  border-collapse: separate;
-  width: 100%;
-}
-
-table.otherinfo th.header{
-  padding-top: 10px;
-  border-bottom: 1px solid gray;
-  font-weight: bold;
-  background-color: white;
-  color: #707040;
-}
-
-table.otherinfo th {
-  border-bottom: 1px solid #afafaf;
-  font-weight: bold;
-  text-align: left;
-}
-
 
 /* style for class list */
 table.classlist {
@@ -305,3 +284,23 @@ table.classhelp td {
 }
 
 
+/* style for "other" displays */
+table.otherinfo {
+  border-spacing: 0px;
+  border-collapse: separate;
+  width: 100%;
+}
+
+table.otherinfo th.header{
+  padding-top: 10px;
+  border-bottom: 1px solid gray;
+  font-weight: bold;
+  background-color: white;
+  color: #707040;
+}
+
+table.otherinfo th {
+  border-bottom: 1px solid #afafaf;
+  font-weight: bold;
+  text-align: left;
+}