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