Skip to content

Commit 7ed80d3

Browse files
author
Richard Jones
committed
Applied Stefan Seefeld's html4/xhtml patch with some changes.
1 parent ec75bcb commit 7ed80d3

File tree

6 files changed

+90
-29
lines changed

6 files changed

+90
-29
lines changed

CHANGES.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ Feature:
2121
828963)
2222
- ignore incoming email with "Precedence: bulk" (sf patch 843489)
2323
- use HTTP 'Content-Length' header (modified sf patch 844577)
24+
- HTML generated is now HTML4 (or optionally XHTML) compliant (sf feature
25+
814314 and sf patch 834620)
2426

2527
Fixed:
2628
- mysql documentation fixed to note requirement of 4.0+ and InnoDB

doc/customizing.txt

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
Customising Roundup
33
===================
44

5-
:Version: $Revision: 1.105 $
5+
:Version: $Revision: 1.106 $
66

77
.. This document borrows from the ZopeBook section on ZPT. The original is at:
88
http://www.zope.org/Documentation/Books/ZopeBook/current/ZPT.stx
@@ -180,6 +180,11 @@ The configuration variables available are:
180180
Default class to use in the mailgw if one isn't supplied in email
181181
subjects. To disable, comment out the variable below or leave it blank.
182182

183+
**HTML_VERSION** - ``'html4'`` or ``'xhtml'``
184+
HTML version to generate. The templates are html4 by default. If you
185+
wish to make them xhtml, then you'll need to change this var to 'xhtml'
186+
too so all auto-generated HTML is compliant.
187+
183188
The default config.py is given below - as you
184189
can see, the MAIL_DOMAIN must be edited before any interaction with the
185190
tracker is attempted.::
@@ -255,6 +260,11 @@ tracker is attempted.::
255260
MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default
256261
#MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out)
257262

263+
# HTML version to generate. The templates are html4 by default. If you
264+
# wish to make them xhtml, then you'll need to change this var to 'xhtml'
265+
# too so all auto-generated HTML is compliant.
266+
HTML_VERSION = 'html4' # either 'html4' or 'xhtml'
267+
258268
#
259269
# SECURITY DEFINITIONS
260270
#
@@ -1054,6 +1064,10 @@ returning.
10541064
Default templates
10551065
-----------------
10561066

1067+
The default templates are html4 compliant. If you wish to change them to be
1068+
xhtml compliant, you'll need to change the ``HTML_VERSION`` configuration
1069+
variable in ``config.py`` to ``'xhtml'`` instead of ``'html4'``.
1070+
10571071
Most customisation of the web view can be done by modifying the
10581072
templates in the tracker ``'html'`` directory. There are several types
10591073
of files in there. The *minimal* template includes:

doc/index.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ implement this system on their time.
4949

5050
Thanks also to the many people on the mailing list, in the sourceforge
5151
project and those who just report bugs:
52+
Thomas Arendsen Hein,
5253
Anthony Baxter,
5354
Cameron Blackwood,
5455
Jeff Blaine,
@@ -66,7 +67,6 @@ Johannes Gijsbers,
6667
Gus Gollings,
6768
Dan Grassi,
6869
Engelbert Gruber,
69-
Thomas Arendsen Hein,
7070
Juergen Hermann,
7171
Tobias Hunger,
7272
James Kew,

roundup/cgi/templating.py

Lines changed: 60 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,14 @@
2424
from roundup.cgi.TAL.TALInterpreter import TALInterpreter
2525
from roundup.cgi import ZTUtils
2626

27+
def input_html4(**attrs):
28+
"""Generate an 'input' (html4) element with given attributes"""
29+
return '<input %s>'%' '.join(['%s="%s"'%item for item in attrs.items()])
30+
31+
def input_xhtml(**attrs):
32+
"""Generate an 'input' (xhtml) element with given attributes"""
33+
return '<input %s/>'%' '.join(['%s="%s"'%item for item in attrs.items()])
34+
2735
class NoTemplate(Exception):
2836
pass
2937

@@ -295,6 +303,14 @@ def __init__(self, client, classname, anonymous=0):
295303
self._klass = self._db.getclass(self.classname)
296304
self._props = self._klass.getprops()
297305

306+
html_version = 'html4'
307+
if hasattr(self._client.instance.config, 'HTML_VERSION'):
308+
html_version = self._client.instance.config.HTML_VERSION
309+
if html_version == 'xhtml':
310+
self.input = input_xhtml
311+
else:
312+
self.input = input_html4
313+
298314
def __repr__(self):
299315
return '<HTMLClass(0x%x) %s>'%(id(self), self.classname)
300316

@@ -478,8 +494,8 @@ def classhelp(self, properties=None, label='(list)', width='500',
478494
def submit(self, label="Submit New Entry"):
479495
''' Generate a submit button (and action hidden element)
480496
'''
481-
return ' <input type="hidden" name="@action" value="new">\n'\
482-
' <input type="submit" name="submit" value="%s">'%label
497+
return self.input(type="hidden",name="@action",value="new") + '\n' + \
498+
self.input(type="submit",name="submit",value=label)
483499

484500
def history(self):
485501
return 'New node - no history'
@@ -556,8 +572,8 @@ def designator(self):
556572
def submit(self, label="Submit Changes"):
557573
''' Generate a submit button (and action hidden element)
558574
'''
559-
return ' <input type="hidden" name="@action" value="edit">\n'\
560-
' <input type="submit" name="submit" value="%s">'%label
575+
return self.input(type="hidden",name="@action",value="edit") + '\n' + \
576+
self.input(type="submit",name="submit",value=label)
561577

562578
def journal(self, direction='descending'):
563579
''' Return a list of HTMLJournalEntry instances.
@@ -844,6 +860,15 @@ def __init__(self, client, classname, nodeid, prop, name, value,
844860
self._formname = '%s%s@%s'%(classname, nodeid, name)
845861
else:
846862
self._formname = name
863+
864+
html_version = 'html4'
865+
if hasattr(self._client.instance.config, 'HTML_VERSION'):
866+
html_version = self._client.instance.config.HTML_VERSION
867+
if html_version == 'xhtml':
868+
self.input = input_xhtml
869+
else:
870+
self.input = input_html4
871+
847872
def __repr__(self):
848873
return '<HTMLProperty(0x%x) %s %r %r>'%(id(self), self._formname,
849874
self._prop, self._value)
@@ -918,7 +943,7 @@ def field(self, size = 30):
918943
else:
919944
value = cgi.escape(str(self._value))
920945
value = '&quot;'.join(value.split('"'))
921-
return '<input name="%s" value="%s" size="%s">'%(self._formname, value, size)
946+
return self.input(name=self._formname,value=value,size=size)
922947

923948
def multiline(self, escape=0, rows=5, cols=40):
924949
''' Render a multiline form edit field for the property
@@ -958,15 +983,15 @@ def plain(self):
958983
def field(self, size = 30):
959984
''' Render a form edit field for the property.
960985
'''
961-
return '<input type="password" name="%s" size="%s">'%(self._formname, size)
986+
return self.input(type="password", name=self._formname, size=size)
962987

963988
def confirm(self, size = 30):
964989
''' Render a second form edit field for the property, used for
965990
confirmation that the user typed the password correctly. Generates
966991
a field with name "@confirm@name".
967992
'''
968-
return '<input type="password" name="@confirm@%s" size="%s">'%(
969-
self._formname, size)
993+
return self.input(type="password", name="@confirm@%s"%self._formname,
994+
size=size)
970995

971996
class NumberHTMLProperty(HTMLProperty):
972997
def plain(self):
@@ -982,7 +1007,7 @@ def field(self, size = 30):
9821007
else:
9831008
value = cgi.escape(str(self._value))
9841009
value = '&quot;'.join(value.split('"'))
985-
return '<input name="%s" value="%s" size="%s">'%(self._formname, value, size)
1010+
return self.input(name=self._formname,value=value,size=size)
9861011

9871012
def __int__(self):
9881013
''' Return an int of me
@@ -1007,14 +1032,16 @@ def field(self):
10071032
''' Render a form edit field for the property
10081033
'''
10091034
checked = self._value and "checked" or ""
1010-
s = '<input type="radio" name="%s" value="yes" %s>Yes'%(self._formname,
1011-
checked)
1012-
if checked:
1013-
checked = ""
1035+
if self._value:
1036+
s = self.input(type="radio",name=self._formname,value="yes",checked="checked")
1037+
s += 'Yes'
1038+
s +=self.input(type="radio",name=self._formname,value="no")
1039+
s += 'No'
10141040
else:
1015-
checked = "checked"
1016-
s += '<input type="radio" name="%s" value="no" %s>No'%(self._formname,
1017-
checked)
1041+
s = self.input(type="radio",name=self._formname,value="yes")
1042+
s += 'Yes'
1043+
s +=self.input(type="radio",name=self._formname,value="no",checked="checked")
1044+
s += 'No'
10181045
return s
10191046

10201047
class DateHTMLProperty(HTMLProperty):
@@ -1042,7 +1069,7 @@ def field(self, size = 30):
10421069
else:
10431070
value = cgi.escape(str(self._value.local(self._db.getUserTimezone())))
10441071
value = '&quot;'.join(value.split('"'))
1045-
return '<input name="%s" value="%s" size="%s">'%(self._formname, value, size)
1072+
return self.input(name=self._formname,value=value,size=size)
10461073

10471074
def reldate(self, pretty=1):
10481075
''' Render the interval between the date and now.
@@ -1099,7 +1126,7 @@ def field(self, size = 30):
10991126
else:
11001127
value = cgi.escape(str(self._value))
11011128
value = '&quot;'.join(value.split('"'))
1102-
return '<input name="%s" value="%s" size="%s">'%(self._formname, value, size)
1129+
return self.input(name=self._formname,value=value,size=size)
11031130

11041131
class LinkHTMLProperty(HTMLProperty):
11051132
''' Link HTMLProperty
@@ -1155,7 +1182,7 @@ def field(self, showid=0, size=None):
11551182
l = ['<select name="%s">'%self._formname]
11561183
k = linkcl.labelprop(1)
11571184
if self._value is None:
1158-
s = 'selected '
1185+
s = 'selected="selected" '
11591186
else:
11601187
s = ''
11611188
l.append(_('<option %svalue="-1">- no selection -</option>')%s)
@@ -1171,7 +1198,7 @@ def field(self, showid=0, size=None):
11711198
# figure if this option is selected
11721199
s = ''
11731200
if optionid == self._value:
1174-
s = 'selected '
1201+
s = 'selected="selected" '
11751202

11761203
# figure the label
11771204
if showid:
@@ -1200,7 +1227,7 @@ def menu(self, size=None, height=None, showid=0, additional=[],
12001227
k = linkcl.labelprop(1)
12011228
s = ''
12021229
if value is None:
1203-
s = 'selected '
1230+
s = 'selected="selected" '
12041231
l.append(_('<option %svalue="-1">- no selection -</option>')%s)
12051232
if linkcl.getprops().has_key('order'):
12061233
sort_on = ('+', 'order')
@@ -1219,7 +1246,7 @@ def menu(self, size=None, height=None, showid=0, additional=[],
12191246
# figure if this option is selected
12201247
s = ''
12211248
if value in [optionid, option]:
1222-
s = 'selected '
1249+
s = 'selected="selected" '
12231250

12241251
# figure the label
12251252
if showid:
@@ -1315,7 +1342,7 @@ def field(self, size=30, showid=0):
13151342
k = linkcl.labelprop(1)
13161343
value = [linkcl.get(v, k) for v in value]
13171344
value = cgi.escape(','.join(value))
1318-
return '<input name="%s" size="%s" value="%s">'%(self._formname, size, value)
1345+
return self.input(name=self._formname,size=size,value=value)
13191346

13201347
def menu(self, size=None, height=None, showid=0, additional=[],
13211348
**conditions):
@@ -1342,7 +1369,7 @@ def menu(self, size=None, height=None, showid=0, additional=[],
13421369
# figure if this option is selected
13431370
s = ''
13441371
if optionid in value or option in value:
1345-
s = 'selected '
1372+
s = 'selected="selected" '
13461373

13471374
# figure the label
13481375
if showid:
@@ -1451,6 +1478,14 @@ def __init__(self, client):
14511478
# the special char to use for special vars
14521479
self.special_char = '@'
14531480

1481+
html_version = 'html4'
1482+
if hasattr(self.client.instance.config, 'HTML_VERSION'):
1483+
html_version = self.client.instance.config.HTML_VERSION
1484+
if html_version == 'xhtml':
1485+
self.input = input_xhtml
1486+
else:
1487+
self.input = input_html4
1488+
14541489
self._post_init()
14551490

14561491
def _post_init(self):
@@ -1603,7 +1638,7 @@ def indexargs_form(self, columns=1, sort=1, group=1, filter=1,
16031638
''' return the current index args as form elements '''
16041639
l = []
16051640
sc = self.special_char
1606-
s = '<input type="hidden" name="%s" value="%s">'
1641+
s = self.input(type="hidden",name="%s",value="%s")
16071642
if columns and self.columns:
16081643
l.append(s%(sc+'columns', ','.join(self.columns)))
16091644
if sort and self.sort[1] is not None:

templates/classic/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: config.py,v 1.3 2003-04-24 07:19:59 richard Exp $
18+
# $Id: config.py,v 1.4 2003-12-06 00:00:54 richard Exp $
1919

2020
import os
2121

@@ -106,6 +106,11 @@
106106
MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default
107107
#MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out)
108108

109+
# HTML version to generate. The templates are html4 by default. If you
110+
# wish to make them xhtml, then you'll need to change this var to 'xhtml'
111+
# too so all auto-generated HTML is compliant.
112+
HTML_VERSION = 'html4' # either 'html4' or 'xhtml'
113+
109114
#
110115
# SECURITY DEFINITIONS
111116
#

templates/minimal/config.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
# BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE,
1616
# SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
1717
#
18-
# $Id: config.py,v 1.2 2003-04-24 07:20:00 richard Exp $
18+
# $Id: config.py,v 1.3 2003-12-06 00:00:54 richard Exp $
1919

2020
import os
2121

@@ -110,4 +110,9 @@
110110
MAIL_DEFAULT_CLASS = 'issue' # use "issue" class by default
111111
#MAIL_DEFAULT_CLASS = '' # disable (or just comment the var out)
112112

113+
# HTML version to generate. The templates are html4 by default. If you
114+
# wish to make them xhtml, then you'll need to change this var to 'xhtml'
115+
# too so all auto-generated HTML is compliant.
116+
HTML_VERSION = 'html4' # either 'html4' or 'xhtml'
117+
113118
# vim: set filetype=python ts=4 sw=4 et si

0 commit comments

Comments
 (0)