or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

application-routing.mdindex.mdplugin-system.mdrequest-handling.mdresponse-management.mdserver-management.mdstatic-utilities.mdtemplate-rendering.md

template-rendering.mddocs/

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

```