Skip to content

Commit 2a23c9a

Browse files
committed
Provide ability to specify arbitrary HTML attributes.
1 parent a639d97 commit 2a23c9a

File tree

1 file changed

+42
-28
lines changed

1 file changed

+42
-28
lines changed

roundup/cgi/templating.py

Lines changed: 42 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -420,17 +420,19 @@ def _set_input_default_args(dic):
420420
except KeyError:
421421
pass
422422

423+
def cgi_escape_attrs(**attrs):
424+
return ' '.join(['%s="%s"'%(k,cgi.escape(str(v), True))
425+
for k,v in attrs.items()])
426+
423427
def input_html4(**attrs):
424428
"""Generate an 'input' (html4) element with given attributes"""
425429
_set_input_default_args(attrs)
426-
return '<input %s>'%' '.join(['%s="%s"'%(k,cgi.escape(str(v), True))
427-
for k,v in attrs.items()])
430+
return '<input %s>'%cgi_escape_attrs(**attrs)
428431

429432
def input_xhtml(**attrs):
430433
"""Generate an 'input' (xhtml) element with given attributes"""
431434
_set_input_default_args(attrs)
432-
return '<input %s/>'%' '.join(['%s="%s"'%(k,cgi.escape(str(v), True))
433-
for k,v in attrs.items()])
435+
return '<input %s/>'%cgi_escape_attrs(**attrs)
434436

435437
class HTMLInputMixin:
436438
""" requires a _client property """
@@ -1464,8 +1466,7 @@ def multiline(self, escape=0, rows=5, cols=40, **kwargs):
14641466

14651467
value = '&quot;'.join(value.split('"'))
14661468
name = self._formname
1467-
passthrough_args = ' '.join(['%s="%s"' % (k, cgi.escape(str(v), True))
1468-
for k,v in kwargs.items()])
1469+
passthrough_args = cgi_escape_attrs(**kwargs)
14691470
return ('<textarea %(passthrough_args)s name="%(name)s" id="%(name)s"'
14701471
' rows="%(rows)s" cols="%(cols)s">'
14711472
'%(value)s</textarea>') % locals()
@@ -1503,15 +1504,16 @@ def plain(self, escape=0):
15031504
return ''
15041505
return self._('*encrypted*')
15051506

1506-
def field(self, size=30):
1507+
def field(self, size=30, **kwargs):
15071508
""" Render a form edit field for the property.
15081509
15091510
If not editable, just display the value via plain().
15101511
"""
15111512
if not self.is_edit_ok():
15121513
return self.plain(escape=1)
15131514

1514-
return self.input(type="password", name=self._formname, size=size)
1515+
return self.input(type="password", name=self._formname, size=size,
1516+
**kwargs)
15151517

15161518
def confirm(self, size=30):
15171519
""" Render a second form edit field for the property, used for
@@ -1540,7 +1542,7 @@ def plain(self, escape=0):
15401542

15411543
return str(self._value)
15421544

1543-
def field(self, size=30):
1545+
def field(self, size=30, **kwargs):
15441546
""" Render a form edit field for the property.
15451547
15461548
If not editable, just display the value via plain().
@@ -1552,7 +1554,8 @@ def field(self, size=30):
15521554
if value is None:
15531555
value = ''
15541556

1555-
return self.input(name=self._formname, value=value, size=size)
1557+
return self.input(name=self._formname, value=value, size=size,
1558+
**kwargs)
15561559

15571560
def __int__(self):
15581561
""" Return an int of me
@@ -1576,7 +1579,7 @@ def plain(self, escape=0):
15761579
return ''
15771580
return self._value and self._("Yes") or self._("No")
15781581

1579-
def field(self):
1582+
def field(self, **kwargs):
15801583
""" Render a form edit field for the property
15811584
15821585
If not editable, just display the value via plain().
@@ -1592,15 +1595,17 @@ def field(self):
15921595
checked = value and "checked" or ""
15931596
if value:
15941597
s = self.input(type="radio", name=self._formname, value="yes",
1595-
checked="checked")
1598+
checked="checked", **kwargs)
15961599
s += self._('Yes')
1597-
s +=self.input(type="radio", name=self._formname, value="no")
1600+
s +=self.input(type="radio", name=self._formname, value="no",
1601+
**kwargs)
15981602
s += self._('No')
15991603
else:
1600-
s = self.input(type="radio", name=self._formname, value="yes")
1604+
s = self.input(type="radio", name=self._formname, value="yes",
1605+
**kwargs)
16011606
s += self._('Yes')
16021607
s +=self.input(type="radio", name=self._formname, value="no",
1603-
checked="checked")
1608+
checked="checked", **kwargs)
16041609
s += self._('No')
16051610
return s
16061611

@@ -1658,7 +1663,8 @@ def now(self, str_interval=None):
16581663
return DateHTMLProperty(self._client, self._classname, self._nodeid,
16591664
self._prop, self._formname, ret)
16601665

1661-
def field(self, size=30, default=None, format=_marker, popcal=True):
1666+
def field(self, size=30, default=None, format=_marker, popcal=True,
1667+
**kwargs):
16621668
"""Render a form edit field for the property
16631669
16641670
If not editable, just display the value via plain().
@@ -1693,7 +1699,8 @@ def field(self, size=30, default=None, format=_marker, popcal=True):
16931699
elif isinstance(value, str) or isinstance(value, unicode):
16941700
# most likely erroneous input to be passed back to user
16951701
if isinstance(value, unicode): value = value.encode('utf8')
1696-
return self.input(name=self._formname, value=value, size=size)
1702+
return self.input(name=self._formname, value=value, size=size,
1703+
**kwargs)
16971704
else:
16981705
raw_value = value
16991706

@@ -1713,7 +1720,8 @@ def field(self, size=30, default=None, format=_marker, popcal=True):
17131720
if format is not self._marker:
17141721
value = value.pretty(format)
17151722

1716-
s = self.input(name=self._formname, value=value, size=size)
1723+
s = self.input(name=self._formname, value=value, size=size,
1724+
**kwargs)
17171725
if popcal:
17181726
s += self.popcal()
17191727
return s
@@ -1808,7 +1816,7 @@ def pretty(self):
18081816

18091817
return self._value.pretty()
18101818

1811-
def field(self, size=30):
1819+
def field(self, size=30, **kwargs):
18121820
""" Render a form edit field for the property
18131821
18141822
If not editable, just display the value via plain().
@@ -1820,7 +1828,8 @@ def field(self, size=30):
18201828
if value is None:
18211829
value = ''
18221830

1823-
return self.input(name=self._formname, value=value, size=size)
1831+
return self.input(name=self._formname, value=value, size=size,
1832+
**kwargs)
18241833

18251834
class LinkHTMLProperty(HTMLProperty):
18261835
""" Link HTMLProperty
@@ -1873,7 +1882,7 @@ def plain(self, escape=0):
18731882
value = cgi.escape(value)
18741883
return value
18751884

1876-
def field(self, showid=0, size=None):
1885+
def field(self, showid=0, size=None, **kwargs):
18771886
""" Render a form edit field for the property
18781887
18791888
If not editable, just display the value via plain().
@@ -1891,10 +1900,11 @@ def field(self, showid=0, size=None):
18911900
value = linkcl.get(self._value, k)
18921901
else:
18931902
value = self._value
1894-
return self.input(name=self._formname, value=value, size=size)
1903+
return self.input(name=self._formname, value=value, size=size,
1904+
**kwargs)
18951905

18961906
def menu(self, size=None, height=None, showid=0, additional=[], value=None,
1897-
sort_on=None, **conditions):
1907+
sort_on=None, html_kwargs = {}, **conditions):
18981908
""" Render a form select list for this property
18991909
19001910
"size" is used to limit the length of the list labels
@@ -1927,7 +1937,8 @@ def menu(self, size=None, height=None, showid=0, additional=[], value=None,
19271937
value = None
19281938

19291939
linkcl = self._db.getclass(self._prop.classname)
1930-
l = ['<select name="%s">'%self._formname]
1940+
l = ['<select %s>'%cgi_escape_attrs(name = self._formname,
1941+
**html_kwargs)]
19311942
k = linkcl.labelprop(1)
19321943
s = ''
19331944
if value is None:
@@ -2093,7 +2104,7 @@ def plain(self, escape=0):
20932104
value = cgi.escape(value)
20942105
return value
20952106

2096-
def field(self, size=30, showid=0):
2107+
def field(self, size=30, showid=0, **kwargs):
20972108
""" Render a form edit field for the property
20982109
20992110
If not editable, just display the value via plain().
@@ -2110,10 +2121,11 @@ def field(self, size=30, showid=0):
21102121
k = linkcl.labelprop(1)
21112122
value = lookupKeys(linkcl, k, value)
21122123
value = ','.join(value)
2113-
return self.input(name=self._formname, size=size, value=value)
2124+
return self.input(name=self._formname, size=size, value=value,
2125+
**kwargs)
21142126

21152127
def menu(self, size=None, height=None, showid=0, additional=[],
2116-
value=None, sort_on=None, **conditions):
2128+
value=None, sort_on=None, html_kwargs = {}, **conditions):
21172129
""" Render a form <select> list for this property.
21182130
21192131
"size" is used to limit the length of the list labels
@@ -2166,7 +2178,9 @@ def menu(self, size=None, height=None, showid=0, additional=[],
21662178
# The "no selection" option.
21672179
height += 1
21682180
height = min(height, 7)
2169-
l = ['<select multiple name="%s" size="%s">'%(self._formname, height)]
2181+
l = ['<select multiple %s>'%cgi_escape_attrs(name = self._formname,
2182+
size = height,
2183+
**html_kwargs)]
21702184
k = linkcl.labelprop(1)
21712185

21722186
if value:

0 commit comments

Comments
 (0)