0
# Template Rendering
1
2
Built-in template engine with support for external template systems including Jinja2, Mako, and Cheetah, plus template rendering functions and decorators.
3
4
## Capabilities
5
6
### Template Functions
7
8
Render templates with data and use templates as decorators.
9
10
```python { .api }
11
def template(name, **kwargs):
12
"""
13
Render a template with keyword arguments.
14
15
Parameters:
16
- name: str, template name or template string
17
- **kwargs: template variables
18
19
Returns:
20
str: rendered template
21
"""
22
23
def view(tpl_name, **defaults):
24
"""
25
Decorator that renders a template with the return value of the wrapped function.
26
27
Parameters:
28
- tpl_name: str, template name
29
- **defaults: default template variables
30
31
Returns:
32
function: decorator function
33
"""
34
35
def mako_template(name, **kwargs):
36
"""
37
Render a Mako template.
38
39
Parameters:
40
- name: str, template name
41
- **kwargs: template variables
42
43
Returns:
44
str: rendered template
45
"""
46
47
def jinja2_template(name, **kwargs):
48
"""
49
Render a Jinja2 template.
50
51
Parameters:
52
- name: str, template name
53
- **kwargs: template variables
54
55
Returns:
56
str: rendered template
57
"""
58
59
def cheetah_template(name, **kwargs):
60
"""
61
Render a Cheetah template.
62
63
Parameters:
64
- name: str, template name
65
- **kwargs: template variables
66
67
Returns:
68
str: rendered template
69
"""
70
71
def mako_view(tpl_name, **defaults):
72
"""
73
View decorator using Mako template engine.
74
75
Parameters:
76
- tpl_name: str, template name
77
- **defaults: default template variables
78
79
Returns:
80
function: decorator function
81
"""
82
83
def jinja2_view(tpl_name, **defaults):
84
"""
85
View decorator using Jinja2 template engine.
86
87
Parameters:
88
- tpl_name: str, template name
89
- **defaults: default template variables
90
91
Returns:
92
function: decorator function
93
"""
94
95
def cheetah_view(tpl_name, **defaults):
96
"""
97
View decorator using Cheetah template engine.
98
99
Parameters:
100
- tpl_name: str, template name
101
- **defaults: default template variables
102
103
Returns:
104
function: decorator function
105
"""
106
```
107
108
Usage:
109
110
```python
111
# Direct template rendering
112
@route('/hello/<name>')
113
def hello(name):
114
return template('hello.html', name=name, title='Greeting')
115
116
# Template decorator
117
@route('/user/<id:int>')
118
@view('user.html')
119
def show_user(id):
120
user = get_user(id)
121
return {'user': user, 'title': f'User {id}'}
122
123
# Inline template
124
@route('/simple')
125
def simple():
126
return template('<h1>Hello {{name}}!</h1>', name='World')
127
```
128
129
### Built-in Template Engine
130
131
Bottle's SimpleTemplate engine with Python-like syntax.
132
133
```python { .api }
134
class SimpleTemplate:
135
def __init__(self, source, **options):
136
"""
137
Create template from source string.
138
139
Parameters:
140
- source: str, template source code
141
- **options: template options (name, filename, lookup, encoding, etc.)
142
"""
143
144
def render(self, **kwargs):
145
"""
146
Render template with variables.
147
148
Parameters:
149
- **kwargs: template variables
150
151
Returns:
152
str: rendered template
153
"""
154
155
@property
156
def code(self) -> str:
157
"""Generated Python code for this template."""
158
159
@property
160
def syntax(self) -> str:
161
"""Template syntax tokens."""
162
163
def set_syntax(self, syntax):
164
"""Set template syntax tokens."""
165
```
166
167
Template syntax:
168
169
```html
170
<!-- Simple variable substitution -->
171
<h1>Hello {{name}}!</h1>
172
173
<!-- Python expressions -->
174
<p>Price: ${{price * 1.08}}</p>
175
176
<!-- Conditional statements -->
177
% if user.is_admin:
178
<p>Admin panel</p>
179
% end
180
181
<!-- Loops -->
182
% for item in items:
183
<li>{{item.name}} - ${{item.price}}</li>
184
% end
185
186
<!-- Include other templates -->
187
% include('header.html')
188
189
<!-- Python code blocks -->
190
<%
191
import datetime
192
now = datetime.datetime.now()
193
%>
194
<p>Generated at {{now}}</p>
195
```
196
197
### External Template Engines
198
199
Adapters for popular Python template engines.
200
201
#### Jinja2 Templates
202
203
```python { .api }
204
class Jinja2Template:
205
def __init__(self, source, **options):
206
"""
207
Jinja2 template adapter.
208
209
Parameters:
210
- source: str, template source or filename
211
- **options: Jinja2 environment options
212
"""
213
214
def render(self, **kwargs):
215
"""Render Jinja2 template with variables."""
216
```
217
218
Usage:
219
220
```python
221
# Configure Jinja2
222
from bottle import Jinja2Template
223
Jinja2Template.settings = {
224
'autoescape': True,
225
'loader': jinja2.FileSystemLoader('./templates')
226
}
227
228
@route('/jinja/<name>')
229
@view('hello.j2', template_adapter=Jinja2Template)
230
def jinja_hello(name):
231
return {'name': name}
232
```
233
234
#### Mako Templates
235
236
```python { .api }
237
class MakoTemplate:
238
def __init__(self, source, **options):
239
"""
240
Mako template adapter.
241
242
Parameters:
243
- source: str, template source or filename
244
- **options: Mako template options
245
"""
246
247
def render(self, **kwargs):
248
"""Render Mako template with variables."""
249
```
250
251
#### Cheetah Templates
252
253
```python { .api }
254
class CheetahTemplate:
255
def __init__(self, source, **options):
256
"""
257
Cheetah template adapter.
258
259
Parameters:
260
- source: str, template source or filename
261
- **options: Cheetah template options
262
"""
263
264
def render(self, **kwargs):
265
"""Render Cheetah template with variables."""
266
```
267
268
### Template Configuration
269
270
Configure template search paths and caching.
271
272
```python { .api }
273
class BaseTemplate:
274
settings = {} # Global template settings
275
276
@classmethod
277
def search(cls, name, lookup=None):
278
"""
279
Search for template file.
280
281
Parameters:
282
- name: str, template name
283
- lookup: list, search paths
284
285
Returns:
286
str: template file path
287
"""
288
289
@classmethod
290
def global_config(cls, key, *args):
291
"""Get or set global template configuration."""
292
```
293
294
Configuration options:
295
296
```python
297
# Set template search paths
298
SimpleTemplate.settings['lookup'] = ['./templates', './views']
299
300
# Enable template caching
301
SimpleTemplate.settings['cache'] = True
302
303
# Set default encoding
304
SimpleTemplate.settings['encoding'] = 'utf-8'
305
306
# Custom template syntax
307
SimpleTemplate.settings['syntax'] = '<% %> % {{ }}'
308
```
309
310
### Template Plugin
311
312
Automatic template rendering plugin for return values.
313
314
```python { .api }
315
class TemplatePlugin:
316
def __init__(self):
317
"""Template plugin for automatic template rendering."""
318
319
def apply(self, callback, route):
320
"""Apply plugin to route callback."""
321
```
322
323
The template plugin automatically renders templates when:
324
- Route returns a dictionary
325
- Route has a template name configured
326
- Template decorator is used
327
328
## Template Utilities
329
330
### Template Lookup
331
332
Template file discovery and loading.
333
334
```python { .api }
335
def cached_property(func):
336
"""Decorator for cached template properties."""
337
338
class ResourceManager:
339
def __init__(self):
340
"""Manage template and resource files."""
341
342
def add_path(self, path):
343
"""Add template search path."""
344
345
def lookup(self, name):
346
"""Find template file in search paths."""
347
```
348
349
### Template Errors
350
351
Template-specific exceptions.
352
353
```python { .api }
354
class TemplateError(BottleException):
355
def __init__(self, message):
356
"""Base template error exception."""
357
358
class StplSyntaxError(TemplateError):
359
def __init__(self, message, source=None, line=None):
360
"""Simple template syntax error."""
361
```
362
363
## Advanced Template Features
364
365
### Template Inheritance
366
367
Using template inheritance with external engines:
368
369
```python
370
# With Jinja2
371
@route('/page')
372
@view('page.j2', template_adapter=Jinja2Template)
373
def page():
374
return {
375
'title': 'My Page',
376
'content': 'Page content here'
377
}
378
```
379
380
Template file (`page.j2`):
381
```html
382
{% extends "base.j2" %}
383
{% block title %}{{ title }}{% endblock %}
384
{% block content %}
385
<h1>{{ title }}</h1>
386
<p>{{ content }}</p>
387
{% endblock %}
388
```
389
390
### Custom Template Adapters
391
392
Create custom template engine adapters:
393
394
```python
395
class CustomTemplate:
396
def __init__(self, source, **options):
397
self.source = source
398
self.options = options
399
400
def render(self, **kwargs):
401
# Custom rendering logic
402
return self.source.format(**kwargs)
403
404
# Use custom adapter
405
@route('/custom')
406
@view('template.txt', template_adapter=CustomTemplate)
407
def custom():
408
return {'message': 'Hello Custom!'}
409
```
410
411
### Template Context
412
413
Global template context and helpers:
414
415
```python
416
# Add global template functions
417
import bottle
418
419
def url_for(route_name, **kwargs):
420
return bottle.url(route_name, **kwargs)
421
422
def current_user():
423
return request.environ.get('user')
424
425
# Make available in templates
426
SimpleTemplate.defaults = {
427
'url_for': url_for,
428
'current_user': current_user,
429
'app_name': 'My App'
430
}
431
```