X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=roundup%2Fhtmltemplate.py;h=2f6557a1fdb0abba2b3e4d660048c9cfdc2e923b;hb=1941cfdb27feaa4e680a155d978b7cbe102a0dc5;hp=112cb0fc4614dfb43e3d7b7de130d6f736e21ece;hpb=b5b2580d6a0cf9fa8d4cff774ae57c3b8ccd7921;p=roundup.git
diff --git a/roundup/htmltemplate.py b/roundup/htmltemplate.py
index 112cb0f..2f6557a 100644
--- a/roundup/htmltemplate.py
+++ b/roundup/htmltemplate.py
@@ -15,15 +15,15 @@
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
#
-# $Id: htmltemplate.py,v 1.61 2002-01-17 23:04:53 richard Exp $
+# $Id: htmltemplate.py,v 1.89 2002-05-15 06:34:47 richard Exp $
__doc__ = """
Template engine.
"""
-import os, re, StringIO, urllib, cgi, errno
+import os, re, StringIO, urllib, cgi, errno, types, urllib
-import hyperdb, date, password
+import hyperdb, date
from i18n import _
# This imports the StructureText functionality for the do_stext function
@@ -33,7 +33,15 @@ try:
except ImportError:
StructuredText = None
+class MissingTemplateError(ValueError):
+ '''Error raised when a template file is missing
+ '''
+ pass
+
class TemplateFunctions:
+ '''Defines the templating functions that are used in the HTML templates
+ of the roundup web interface.
+ '''
def __init__(self):
self.form = None
self.nodeid = None
@@ -43,6 +51,15 @@ class TemplateFunctions:
if key[:3] == 'do_':
self.globals[key[3:]] = getattr(self, key)
+ # These are added by the subclass where appropriate
+ self.client = None
+ self.instance = None
+ self.templates = None
+ self.classname = None
+ self.db = None
+ self.cl = None
+ self.properties = None
+
def do_plain(self, property, escape=0):
''' display a String property directly;
@@ -58,7 +75,7 @@ class TemplateFunctions:
if self.nodeid:
# make sure the property is a valid one
# TODO: this tests, but we should handle the exception
- prop_test = self.cl.getprops()[property]
+ dummy = self.cl.getprops()[property]
# get the value for this property
try:
@@ -93,9 +110,12 @@ class TemplateFunctions:
elif isinstance(propclass, hyperdb.Multilink):
linkcl = self.db.classes[propclass.classname]
k = linkcl.labelprop()
- value = ', '.join(value)
+ labels = []
+ for v in value:
+ labels.append(linkcl.get(v, k))
+ value = ', '.join(labels)
else:
- s = _('Plain: bad propclass "%(propclass)s"')%locals()
+ value = _('Plain: bad propclass "%(propclass)s"')%locals()
if escape:
value = cgi.escape(value)
return value
@@ -109,43 +129,61 @@ class TemplateFunctions:
return s
return StructuredText(s,level=1,header=0)
- def do_field(self, property, size=None, height=None, showid=0):
- ''' display a property like the plain displayer, but in a text field
- to be edited
+ def determine_value(self, property):
+ '''determine the value of a property using the node, form or
+ filterspec
'''
- if not self.nodeid and self.form is None and self.filterspec is None:
- return _('[Field: not called from item]')
propclass = self.properties[property]
- if (isinstance(propclass, hyperdb.Link) or
- isinstance(propclass, hyperdb.Multilink)):
- linkcl = self.db.classes[propclass.classname]
- def sortfunc(a, b, cl=linkcl):
- if cl.getprops().has_key('order'):
- sort_on = 'order'
- else:
- sort_on = cl.labelprop()
- r = cmp(cl.get(a, sort_on), cl.get(b, sort_on))
- return r
if self.nodeid:
value = self.cl.get(self.nodeid, property, None)
- # TODO: remove this from the code ... it's only here for
- # handling schema changes, and they should be handled outside
- # of this code...
if isinstance(propclass, hyperdb.Multilink) and value is None:
- value = []
+ return []
+ return value
elif self.filterspec is not None:
if isinstance(propclass, hyperdb.Multilink):
- value = self.filterspec.get(property, [])
+ return self.filterspec.get(property, [])
else:
- value = self.filterspec.get(property, '')
+ return self.filterspec.get(property, '')
+ # TODO: pull the value from the form
+ if isinstance(propclass, hyperdb.Multilink):
+ return []
else:
- # TODO: pull the value from the form
- if isinstance(propclass, hyperdb.Multilink): value = []
- else: value = ''
+ return ''
+
+ def make_sort_function(self, classname):
+ '''Make a sort function for a given class
+ '''
+ linkcl = self.db.classes[classname]
+ if linkcl.getprops().has_key('order'):
+ sort_on = 'order'
+ else:
+ sort_on = linkcl.labelprop()
+ def sortfunc(a, b, linkcl=linkcl, sort_on=sort_on):
+ return cmp(linkcl.get(a, sort_on), linkcl.get(b, sort_on))
+ return sortfunc
+
+ def do_field(self, property, size=None, showid=0):
+ ''' display a property like the plain displayer, but in a text field
+ to be edited
+
+ Note: if you would prefer an option list style display for
+ link or multilink editing, use menu().
+ '''
+ if not self.nodeid and self.form is None and self.filterspec is None:
+ return _('[Field: not called from item]')
+
+ if size is None:
+ size = 30
+
+ propclass = self.properties[property]
+
+ # get the value
+ value = self.determine_value(property)
+
+ # now display
if (isinstance(propclass, hyperdb.String) or
isinstance(propclass, hyperdb.Date) or
isinstance(propclass, hyperdb.Interval)):
- size = size or 30
if value is None:
value = ''
else:
@@ -153,9 +191,13 @@ class TemplateFunctions:
value = '"'.join(value.split('"'))
s = ''%(property, value, size)
elif isinstance(propclass, hyperdb.Password):
- size = size or 30
s = ''%(property, size)
elif isinstance(propclass, hyperdb.Link):
+ sortfunc = self.make_sort_function(propclass.classname)
+ linkcl = self.db.classes[propclass.classname]
+ options = linkcl.list()
+ options.sort(sortfunc)
+ # TODO: make this a field display, not a menu one!
l = ['')
s = '\n'.join(l)
elif isinstance(propclass, hyperdb.Multilink):
- list = linkcl.list()
- list.sort(sortfunc)
- l = []
+ sortfunc = self.make_sort_function(propclass.classname)
+ linkcl = self.db.classes[propclass.classname]
+ if value:
+ value.sort(sortfunc)
# map the id to the label property
- # TODO: allow reversion to the older