comparison roundup/template_funcs.py @ 936:57d09949380e

cleanup
author Richard Jones <richard@users.sourceforge.net>
date Thu, 15 Aug 2002 00:40:10 +0000
parents fdcf16b444a9
children d435bf1ecd8d
comparison
equal deleted inserted replaced
935:2abb6b2697b6 936:57d09949380e
1 #
2 # $Id: template_funcs.py,v 1.2 2002-08-15 00:40:10 richard Exp $
3 #
1 import hyperdb, date, password 4 import hyperdb, date, password
2 from i18n import _ 5 from i18n import _
3 import htmltemplate 6 import htmltemplate
4 import cgi, os, StringIO, urllib, types 7 import cgi, os, StringIO, urllib, types
5 8
6 9 def do_plain(client, classname, cl, props, nodeid, filterspec, property,
7 def do_plain(client, classname, cl, props, nodeid, filterspec, property, escape=0, lookup=1): 10 escape=0, lookup=1):
8 ''' display a String property directly; 11 ''' display a String property directly;
9 12
10 display a Date property in a specified time zone with an option to 13 display a Date property in a specified time zone with an option to
11 omit the time from the date stamp; 14 omit the time from the date stamp;
12 15
50 53
51 if escape: 54 if escape:
52 value = cgi.escape(value) 55 value = cgi.escape(value)
53 return value 56 return value
54 57
55 def do_stext(client, classname, cl, props, nodeid, filterspec, property, escape=0): 58 def do_stext(client, classname, cl, props, nodeid, filterspec, property,
59 escape=0):
56 '''Render as structured text using the StructuredText module 60 '''Render as structured text using the StructuredText module
57 (see above for details) 61 (see above for details)
58 ''' 62 '''
59 s = do_plain(client, classname, cl, props, nodeid, filterspec, property, escape=escape) 63 s = do_plain(client, classname, cl, props, nodeid, filterspec, property,
64 escape=escape)
60 if not StructuredText: 65 if not StructuredText:
61 return s 66 return s
62 return StructuredText(s,level=1,header=0) 67 return StructuredText(s,level=1,header=0)
63 68
64 def determine_value(cl, props, nodeid, filterspec, property): 69 def determine_value(cl, props, nodeid, filterspec, property):
93 sort_on = linkcl.labelprop() 98 sort_on = linkcl.labelprop()
94 def sortfunc(a, b, linkcl=linkcl, sort_on=sort_on): 99 def sortfunc(a, b, linkcl=linkcl, sort_on=sort_on):
95 return cmp(linkcl.get(a, sort_on), linkcl.get(b, sort_on)) 100 return cmp(linkcl.get(a, sort_on), linkcl.get(b, sort_on))
96 return sortfunc 101 return sortfunc
97 102
98 def do_field(client, classname, cl, props, nodeid, filterspec, property, size=None, showid=0): 103 def do_field(client, classname, cl, props, nodeid, filterspec, property,
104 size=None, showid=0):
99 ''' display a property like the plain displayer, but in a text field 105 ''' display a property like the plain displayer, but in a text field
100 to be edited 106 to be edited
101 107
102 Note: if you would prefer an option list style display for 108 Note: if you would prefer an option list style display for
103 link or multilink editing, use menu(). 109 link or multilink editing, use menu().
121 value = cgi.escape(str(value)) 127 value = cgi.escape(str(value))
122 value = '&quot;'.join(value.split('"')) 128 value = '&quot;'.join(value.split('"'))
123 s = '<input name="%s" value="%s" size="%s">'%(property, value, size) 129 s = '<input name="%s" value="%s" size="%s">'%(property, value, size)
124 elif isinstance(propclass, hyperdb.Boolean): 130 elif isinstance(propclass, hyperdb.Boolean):
125 checked = value and "checked" or "" 131 checked = value and "checked" or ""
126 s = '<input type="radio" name="%s" value="yes" %s>Yes'%(property, checked) 132 s = '<input type="radio" name="%s" value="yes" %s>Yes'%(property,
133 checked)
127 if checked: 134 if checked:
128 checked = "" 135 checked = ""
129 else: 136 else:
130 checked = "checked" 137 checked = "checked"
131 s += '<input type="radio" name="%s" value="no" %s>No'%(property, checked) 138 s += '<input type="radio" name="%s" value="no" %s>No'%(property,
139 checked)
132 elif isinstance(propclass, hyperdb.Number): 140 elif isinstance(propclass, hyperdb.Number):
133 s = '<input name="%s" value="%s" size="%s">'%(property, value, size) 141 s = '<input name="%s" value="%s" size="%s">'%(property, value, size)
134 elif isinstance(propclass, hyperdb.Password): 142 elif isinstance(propclass, hyperdb.Password):
135 s = '<input type="password" name="%s" size="%s">'%(property, size) 143 s = '<input type="password" name="%s" size="%s">'%(property, size)
136 elif isinstance(propclass, hyperdb.Link): 144 elif isinstance(propclass, hyperdb.Link):
176 s = '<input name="%s" size="%s" value="%s">'%(property, size, value) 184 s = '<input name="%s" size="%s" value="%s">'%(property, size, value)
177 else: 185 else:
178 s = _('Plain: bad propclass "%(propclass)s"')%locals() 186 s = _('Plain: bad propclass "%(propclass)s"')%locals()
179 return s 187 return s
180 188
181 def do_multiline(client, classname, cl, props, nodeid, filterspec, property, rows=5, cols=40): 189 def do_multiline(client, classname, cl, props, nodeid, filterspec, property,
190 rows=5, cols=40):
182 ''' display a string property in a multiline text edit field 191 ''' display a string property in a multiline text edit field
183 ''' 192 '''
184 if not nodeid and client.form is None and filterspec is None: 193 if not nodeid and client.form is None and filterspec is None:
185 return _('[Multiline: not called from item]') 194 return _('[Multiline: not called from item]')
186 195
197 206
198 # display 207 # display
199 return '<textarea name="%s" rows="%s" cols="%s">%s</textarea>'%( 208 return '<textarea name="%s" rows="%s" cols="%s">%s</textarea>'%(
200 property, rows, cols, value) 209 property, rows, cols, value)
201 210
202 def do_menu(client, classname, cl, props, nodeid, filterspec, property, size=None, height=None, showid=0, 211 def do_menu(client, classname, cl, props, nodeid, filterspec, property,
203 additional=[], **conditions): 212 size=None, height=None, showid=0, additional=[], **conditions):
204 ''' For a Link/Multilink property, display a menu of the available 213 ''' For a Link/Multilink property, display a menu of the available
205 choices 214 choices
206 215
207 If the additional properties are specified, they will be 216 If the additional properties are specified, they will be
208 included in the text of each option in (brackets, with, commas). 217 included in the text of each option in (brackets, with, commas).
292 l.append('</select>') 301 l.append('</select>')
293 return '\n'.join(l) 302 return '\n'.join(l)
294 return _('[Menu: not a link]') 303 return _('[Menu: not a link]')
295 304
296 #XXX deviates from spec 305 #XXX deviates from spec
297 def do_link(client, classname, cl, props, nodeid, filterspec, property=None, is_download=0, showid=0): 306 def do_link(client, classname, cl, props, nodeid, filterspec, property=None,
307 is_download=0, showid=0):
298 '''For a Link or Multilink property, display the names of the linked 308 '''For a Link or Multilink property, display the names of the linked
299 nodes, hyperlinked to the item views on those nodes. 309 nodes, hyperlinked to the item views on those nodes.
300 For other properties, link to this node with the property as the 310 For other properties, link to this node with the property as the
301 text. 311 text.
302 312
362 else: 372 else:
363 if value in ('', None, []): 373 if value in ('', None, []):
364 value = _('[no %(propname)s]')%{'propname':property.capitalize()} 374 value = _('[no %(propname)s]')%{'propname':property.capitalize()}
365 return '<a href="%s%s">%s</a>'%(classname, nodeid, value) 375 return '<a href="%s%s">%s</a>'%(classname, nodeid, value)
366 376
367 def do_count(client, classname, cl, props, nodeid, filterspec, property, **args): 377 def do_count(client, classname, cl, props, nodeid, filterspec, property,
378 **args):
368 ''' for a Multilink property, display a count of the number of links in 379 ''' for a Multilink property, display a count of the number of links in
369 the list 380 the list
370 ''' 381 '''
371 if not nodeid: 382 if not nodeid:
372 return _('[Count: not called from item]') 383 return _('[Count: not called from item]')
378 # figure the length then... 389 # figure the length then...
379 value = cl.get(nodeid, property) 390 value = cl.get(nodeid, property)
380 return str(len(value)) 391 return str(len(value))
381 392
382 # XXX pretty is definitely new ;) 393 # XXX pretty is definitely new ;)
383 def do_reldate(client, classname, cl, props, nodeid, filterspec, property, pretty=0): 394 def do_reldate(client, classname, cl, props, nodeid, filterspec, property,
395 pretty=0):
384 ''' display a Date property in terms of an interval relative to the 396 ''' display a Date property in terms of an interval relative to the
385 current date (e.g. "+ 3w", "- 2d"). 397 current date (e.g. "+ 3w", "- 2d").
386 398
387 with the 'pretty' flag, make it pretty 399 with the 'pretty' flag, make it pretty
388 ''' 400 '''
406 if not nodeid: 418 if not nodeid:
407 return _('now') 419 return _('now')
408 return interval.pretty() 420 return interval.pretty()
409 return str(interval) 421 return str(interval)
410 422
411 def do_download(client, classname, cl, props, nodeid, filterspec, property, **args): 423 def do_download(client, classname, cl, props, nodeid, filterspec, property,
424 **args):
412 ''' show a Link("file") or Multilink("file") property using links that 425 ''' show a Link("file") or Multilink("file") property using links that
413 allow you to download files 426 allow you to download files
414 ''' 427 '''
415 if not nodeid: 428 if not nodeid:
416 return _('[Download: not called from item]') 429 return _('[Download: not called from item]')
417 return do_link(client, classname, cl, props, nodeid, filterspec, property, is_download=1) 430 return do_link(client, classname, cl, props, nodeid, filterspec, property,
418 431 is_download=1)
419 432
420 def do_checklist(client, classname, cl, props, nodeid, filterspec, property, sortby=None): 433 def do_checklist(client, classname, cl, props, nodeid, filterspec, property,
434 sortby=None):
421 ''' for a Link or Multilink property, display checkboxes for the 435 ''' for a Link or Multilink property, display checkboxes for the
422 available choices to permit filtering 436 available choices to permit filtering
423 437
424 sort the checklist by the argument (+/- property name) 438 sort the checklist by the argument (+/- property name)
425 ''' 439 '''
496 # TODO: pull the value from the form 510 # TODO: pull the value from the form
497 return '<textarea name="__note" wrap="hard" rows=%s cols=%s>'\ 511 return '<textarea name="__note" wrap="hard" rows=%s cols=%s>'\
498 '</textarea>'%(rows, cols) 512 '</textarea>'%(rows, cols)
499 513
500 # XXX new function 514 # XXX new function
501 def do_list(client, classname, cl, props, nodeid, filterspec, property, reverse=0, xtracols=None): 515 def do_list(client, classname, cl, props, nodeid, filterspec, property,
516 reverse=0, xtracols=None):
502 ''' list the items specified by property using the standard index for 517 ''' list the items specified by property using the standard index for
503 the class 518 the class
504 ''' 519 '''
505 propcl = props[property] 520 propcl = props[property]
506 if not isinstance(propcl, hyperdb.Multilink): 521 if not isinstance(propcl, hyperdb.Multilink):
521 fp = StringIO.StringIO() 536 fp = StringIO.StringIO()
522 try: 537 try:
523 write_save = client.write 538 write_save = client.write
524 client.write = fp.write 539 client.write = fp.write
525 client.listcontext = ('%s%s' % (classname, nodeid), property) 540 client.listcontext = ('%s%s' % (classname, nodeid), property)
526 index = htmltemplate.IndexTemplate(client, client.instance.TEMPLATES, propcl.classname) 541 index = htmltemplate.IndexTemplate(client, client.instance.TEMPLATES,
542 propcl.classname)
527 index.render(nodeids=value, show_display_form=0, xtracols=xtracols) 543 index.render(nodeids=value, show_display_form=0, xtracols=xtracols)
528 finally: 544 finally:
529 client.listcontext = None 545 client.listcontext = None
530 client.write = write_save 546 client.write = write_save
531 547
532 return fp.getvalue() 548 return fp.getvalue()
533 549
534 # XXX new function 550 # XXX new function
535 def do_history(client, classname, cl, props, nodeid, filterspec, direction='descending'): 551 def do_history(client, classname, cl, props, nodeid, filterspec,
552 direction='descending'):
536 ''' list the history of the item 553 ''' list the history of the item
537 554
538 If "direction" is 'descending' then the most recent event will 555 If "direction" is 'descending' then the most recent event will
539 be displayed first. If it is 'ascending' then the oldest event 556 be displayed first. If it is 'ascending' then the oldest event
540 will be displayed first. 557 will be displayed first.
692 if nodeid or client.form is not None: 709 if nodeid or client.form is not None:
693 return _('<input type="submit" name="submit" value="%s">' % value) 710 return _('<input type="submit" name="submit" value="%s">' % value)
694 else: 711 else:
695 return _('[Submit: not called from item]') 712 return _('[Submit: not called from item]')
696 713
697 def do_classhelp(client, classname, cl, props, nodeid, filterspec, clname, properties, label='?', width='400', 714 def do_classhelp(client, classname, cl, props, nodeid, filterspec, clname,
698 height='400'): 715 properties, label='?', width='400', height='400'):
699 '''pop up a javascript window with class help 716 '''pop up a javascript window with class help
700 717
701 This generates a link to a popup window which displays the 718 This generates a link to a popup window which displays the
702 properties indicated by "properties" of the class named by 719 properties indicated by "properties" of the class named by
703 "classname". The "properties" should be a comma-separated list 720 "classname". The "properties" should be a comma-separated list
708 ''' 725 '''
709 return '<a href="javascript:help_window(\'classhelp?classname=%s&' \ 726 return '<a href="javascript:help_window(\'classhelp?classname=%s&' \
710 'properties=%s\', \'%s\', \'%s\')"><b>(%s)</b></a>'%(clname, 727 'properties=%s\', \'%s\', \'%s\')"><b>(%s)</b></a>'%(clname,
711 properties, width, height, label) 728 properties, width, height, label)
712 729
713 def do_email(client, classname, cl, props, nodeid, filterspec, property, escape=0): 730 def do_email(client, classname, cl, props, nodeid, filterspec, property,
731 escape=0):
714 '''display the property as one or more "fudged" email addrs 732 '''display the property as one or more "fudged" email addrs
715 ''' 733 '''
716 734
717 if not nodeid and client.form is None: 735 if not nodeid and client.form is None:
718 return _('[Email: not called from item]') 736 return _('[Email: not called from item]')
736 value = _('[Email: not a string]')%locals() 754 value = _('[Email: not a string]')%locals()
737 if escape: 755 if escape:
738 value = cgi.escape(value) 756 value = cgi.escape(value)
739 return value 757 return value
740 758
741 def do_filterspec(client, classname, cl, props, nodeid, filterspec, classprop, urlprop): 759 def do_filterspec(client, classname, cl, props, nodeid, filterspec, classprop,
760 urlprop):
761
742 qs = cl.get(nodeid, urlprop) 762 qs = cl.get(nodeid, urlprop)
743 classname = cl.get(nodeid, classprop) 763 classname = cl.get(nodeid, classprop)
744 filterspec = {} 764 filterspec = {}
745 query = cgi.parse_qs(qs) 765 query = cgi.parse_qs(qs)
746 for k,v in query.items(): 766 for k,v in query.items():
749 search_text = query.get('search_text', [''])[0] 769 search_text = query.get('search_text', [''])[0]
750 search_text = urllib.unquote(search_text) 770 search_text = urllib.unquote(search_text)
751 for k,v in query.items(): 771 for k,v in query.items():
752 if k[0] != ':': 772 if k[0] != ':':
753 filterspec[k] = v 773 filterspec[k] = v
754 ixtmplt = htmltemplate.IndexTemplate(client, client.instance.TEMPLATES, classname) 774 ixtmplt = htmltemplate.IndexTemplate(client, client.instance.TEMPLATES,
775 classname)
755 qform = '<form onSubmit="return submit_once()" action="%s%s">\n'%( 776 qform = '<form onSubmit="return submit_once()" action="%s%s">\n'%(
756 classname,nodeid) 777 classname,nodeid)
757 qform += ixtmplt.filter_form(search_text, 778 qform += ixtmplt.filter_form(search_text,
758 query.get(':filter', []), 779 query.get(':filter', []),
759 query.get(':columns', []), 780 query.get(':columns', []),
762 query.get(':sort',[]), 783 query.get(':sort',[]),
763 filterspec, 784 filterspec,
764 pagesize) 785 pagesize)
765 return qform + '</table>\n' 786 return qform + '</table>\n'
766 787
767 def do_href(client, classname, cl, props, nodeid, filterspec, property, prefix='', suffix='', label=''): 788 def do_href(client, classname, cl, props, nodeid, filterspec, property,
789 prefix='', suffix='', label=''):
790 ''' Generate a link to the value of the property, with the form:
791
792 <a href="[prefix][value][suffix]">[label]</a>
793
794 where the [value] is the specified property value.
795 '''
768 value = determine_value(cl, props, nodeid, filterspec, property) 796 value = determine_value(cl, props, nodeid, filterspec, property)
769 return '<a href="%s%s%s">%s</a>' % (prefix, value, suffix, label) 797 return '<a href="%s%s%s">%s</a>'%(prefix, value, suffix, label)
770 798
771 def do_remove(client, classname, cl, props, nodeid, filterspec): 799 def do_remove(client, classname, cl, props, nodeid, filterspec):
772 ''' put a remove href for an item in a list ''' 800 ''' put a remove href for an item in a list '''
773 if not nodeid: 801 if not nodeid:
774 return _('[Remove not called from item]') 802 return _('[Remove not called from item]')
775 try: 803 try:
776 parentdesignator, mlprop = client.listcontext 804 parentdesignator, mlprop = client.listcontext
777 except (AttributeError, TypeError): 805 except (AttributeError, TypeError):
778 return _('[Remove not called form listing of multilink]') 806 return _('[Remove not called form listing of multilink]')
779 return '<a href="remove?:target=%s%s&:multilink=%s:%s">[Remove]</a>' % (classname, nodeid, parentdesignator, mlprop) 807 return '<a href="remove?:target=%s%s&:multilink=%s:%s">[Remove]</a>'%(
780 808 classname, nodeid, parentdesignator, mlprop)
781 809
782 810 #
811 # $Log: not supported by cvs2svn $
812 #
813 #
814 # vim: set filetype=python ts=4 sw=4 et si

Roundup Issue Tracker: http://roundup-tracker.org/