Add custom conversion types for string formatting
You can create a custom formatter for html templates:
import string, cgi
class Template(string.Formatter):
def format_field(self, value, spec):
if spec.endswith('h'):
value = cgi.escape(value)
spec = spec[:-1] + 's'
return super(Template, self).format_field(value, spec)
print Template().format('{0:h} {1:d}', "<hello>", 123)
Note that all conversion takes place inside the template class, no change of input data is required.
Not with %
formatting, no, that is not expandable.
You can specify different formatting options when using the newer format string syntax defined for str.format()
and format()
. Custom types can implement a __format__()
method, and that will be called with the format specification used in the template string:
import cgi
class HTMLEscapedString(unicode):
def __format__(self, spec):
value = unicode(self)
if spec.endswith('h'):
value = cgi.escape(value)
spec = spec[:-1] + 's'
return format(value, spec)
This does require that you use a custom type for your strings:
>>> title = HTMLEscapedString(u'Proof that 12 < 6')
>>> print "<title>{:h}</title>".format(title)
<title>Proof that 12 < 6</title>
For most cases, it is easier just to format the string before handing it to the template, or use a dedicated HTML templating library such as Chameleon, Mako or Jinja2; these handle HTML escaping for you.