1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136
|
The templating language is fairly simple, just {{stuff}}. For
example::
>>> from paste.util.template import Template, sub
>>> sub('Hi {{name}}', name='Ian')
'Hi Ian'
>>> Template('Hi {{repr(name)}}').substitute(name='Ian')
"Hi 'Ian'"
>>> Template('Hi {{name+1}}').substitute(name='Ian') # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
TypeError: cannot concatenate 'str' and 'int' objects at line 1 column 6
It also has Django-style piping::
>>> sub('Hi {{name|repr}}', name='Ian')
"Hi 'Ian'"
Note that None shows up as an empty string::
>>> sub('Hi {{name}}', name=None)
'Hi '
And if/elif/else::
>>> t = Template('{{if x}}{{y}}{{else}}{{z}}{{endif}}')
>>> t.substitute(x=1, y=2, z=3)
'2'
>>> t.substitute(x=0, y=2, z=3)
'3'
>>> t = Template('{{if x > 0}}positive{{elif x < 0}}negative{{else}}zero{{endif}}')
>>> t.substitute(x=1), t.substitute(x=-10), t.substitute(x=0)
('positive', 'negative', 'zero')
Plus a for loop::
>>> t = Template('{{for i in x}}i={{i}}\n{{endfor}}')
>>> t.substitute(x=range(3))
'i=0\ni=1\ni=2\n'
>>> t = Template('{{for a, b in sorted(z.items()):}}{{a}}={{b}},{{endfor}}')
>>> t.substitute(z={1: 2, 3: 4})
'1=2,3=4,'
>>> t = Template('{{for i in x}}{{if not i}}{{break}}'
... '{{endif}}{{i}} {{endfor}}')
>>> t.substitute(x=[1, 2, 0, 3, 4])
'1 2 '
>>> t = Template('{{for i in x}}{{if not i}}{{continue}}'
... '{{endif}}{{i}} {{endfor}}')
>>> t.substitute(x=[1, 2, 0, 3, 0, 4])
'1 2 3 4 '
Also Python blocks::
>>> sub('{{py:\nx=1\n}}{{x}}')
'1'
And some syntax errors::
>>> t = Template('{{if x}}', name='foo.html')
Traceback (most recent call last):
...
TemplateError: No {{endif}} at line 1 column 3 in foo.html
>>> t = Template('{{for x}}', name='foo2.html')
Traceback (most recent call last):
...
TemplateError: Bad for (no "in") in 'x' at line 1 column 3 in foo2.html
There's also an HTMLTemplate that uses HTMLisms::
>>> from paste.util.template import HTMLTemplate, sub_html, html
>>> sub_html('hi {{name}}', name='<foo>')
'hi <foo>'
But if you don't want quoting to happen you can do::
>>> sub_html('hi {{name}}', name=html('<foo>'))
'hi <foo>'
>>> sub_html('hi {{name|html}}', name='<foo>')
'hi <foo>'
Also a couple handy functions;:
>>> t = HTMLTemplate('<a href="article?id={{id|url}}" {{attr(class_=class_)}}>')
>>> t.substitute(id=1, class_='foo')
'<a href="article?id=1" class="foo">'
>>> t.substitute(id='with space', class_=None)
'<a href="article?id=with%20space" >'
There's a handyish looper thing you can also use in your templates (or
in Python, but it's more useful in templates generally)::
>>> from paste.util.looper import looper
>>> seq = ['apple', 'asparagus', 'Banana', 'orange']
>>> for loop, item in looper(seq):
... if item == 'apple':
... assert loop.first
... elif item == 'orange':
... assert loop.last
... if loop.first_group(lambda i: i[0].upper()):
... print('%s:' % item[0].upper())
... print("%s %s" % (loop.number, item))
A:
1 apple
2 asparagus
B:
3 Banana
O:
4 orange
It will also strip out empty lines, when there is a line that only
contains a directive/statement (if/for, etc)::
>>> sub('{{if 1}}\n{{x}}\n{{endif}}\n', x=0)
'0\n'
>>> sub('{{if 1}}x={{x}}\n{{endif}}\n', x=1)
'x=1\n'
>>> sub('{{if 1}}\nx={{x}}\n{{endif}}\n', x=1)
'x=1\n'
Lastly, there is a special directive that will create a default value
for a variable, if no value is given::
>>> sub('{{default x=1}}{{x}}', x=2)
'2'
>>> sub('{{default x=1}}{{x}}')
'1'
>>> # The normal case:
>>> sub('{{x}}') # doctest: +IGNORE_EXCEPTION_DETAIL
Traceback (most recent call last):
...
NameError: name 'x' is not defined at line 1 column 3
And comments work::
>>> sub('Test=x{{#whatever}}')
'Test=x'
|