0
# Templating
1
2
Template rendering system with support for Jinja2 templates and custom template interfaces for building dynamic web applications.
3
4
## Capabilities
5
6
### Template Interface
7
8
Abstract base class for implementing custom template engines.
9
10
```python { .api }
11
from abc import ABC, abstractmethod
12
13
class TemplateInterface(ABC):
14
def __init__(self): ...
15
16
@abstractmethod
17
def render_template(self, *args, **kwargs) -> Response:
18
"""
19
Render a template with given context variables.
20
21
Args:
22
*args: Positional arguments for template rendering
23
**kwargs: Keyword arguments for template context
24
25
Returns:
26
Response object with rendered template content
27
"""
28
```
29
30
### Jinja2 Template Engine
31
32
Built-in Jinja2 template implementation for rendering HTML templates.
33
34
```python { .api }
35
class JinjaTemplate(TemplateInterface):
36
def __init__(
37
self,
38
directory: str,
39
encoding: str = "utf-8",
40
followlinks: bool = False
41
):
42
"""
43
Initialize Jinja2 template engine.
44
45
Args:
46
directory: Directory path containing template files
47
encoding: Template file encoding (default: utf-8)
48
followlinks: Whether to follow symbolic links
49
"""
50
51
def render_template(self, template_name: str, **kwargs) -> Response:
52
"""
53
Render a Jinja2 template with context variables.
54
55
Args:
56
template_name: Name of template file to render
57
**kwargs: Template context variables
58
59
Returns:
60
Response object with rendered HTML content
61
"""
62
```
63
64
## Usage Examples
65
66
### Basic Template Rendering
67
68
```python
69
from robyn import Robyn
70
from robyn.templating import JinjaTemplate
71
72
app = Robyn(__file__)
73
74
# Initialize template engine
75
templates = JinjaTemplate("./templates")
76
77
@app.get("/")
78
def home(request):
79
return templates.render_template(
80
"home.html",
81
title="Welcome",
82
user_name="Alice",
83
items=["Item 1", "Item 2", "Item 3"]
84
)
85
86
@app.get("/profile/<user_id>")
87
def user_profile(request):
88
user_id = request.path_params["user_id"]
89
90
# Fetch user data (example)
91
user_data = {
92
"id": user_id,
93
"name": "John Doe",
94
"email": "john@example.com",
95
"posts": 25
96
}
97
98
return templates.render_template(
99
"profile.html",
100
user=user_data,
101
page_title=f"Profile - {user_data['name']}"
102
)
103
104
app.start()
105
```
106
107
### Template Files
108
109
Example template files in `./templates/` directory:
110
111
**base.html:**
112
```html
113
<!DOCTYPE html>
114
<html>
115
<head>
116
<title>{{ title | default("My App") }}</title>
117
<meta charset="utf-8">
118
</head>
119
<body>
120
<header>
121
<h1>My Web Application</h1>
122
</header>
123
124
<main>
125
{% block content %}{% endblock %}
126
</main>
127
128
<footer>
129
<p>© 2024 My Company</p>
130
</footer>
131
</body>
132
</html>
133
```
134
135
**home.html:**
136
```html
137
{% extends "base.html" %}
138
139
{% block content %}
140
<h2>{{ title }}</h2>
141
<p>Welcome, {{ user_name }}!</p>
142
143
{% if items %}
144
<ul>
145
{% for item in items %}
146
<li>{{ item }}</li>
147
{% endfor %}
148
</ul>
149
{% endif %}
150
{% endblock %}
151
```
152
153
**profile.html:**
154
```html
155
{% extends "base.html" %}
156
157
{% block content %}
158
<div class="profile">
159
<h2>User Profile</h2>
160
<div class="user-info">
161
<p><strong>Name:</strong> {{ user.name }}</p>
162
<p><strong>Email:</strong> {{ user.email }}</p>
163
<p><strong>Posts:</strong> {{ user.posts }}</p>
164
</div>
165
</div>
166
{% endblock %}
167
```
168
169
### Custom Template Engine
170
171
```python
172
from robyn import Robyn, Response, Headers, status_codes
173
from robyn.templating import TemplateInterface
174
175
class CustomTemplateEngine(TemplateInterface):
176
def __init__(self, template_dir: str):
177
self.template_dir = template_dir
178
179
def render_template(self, template_name: str, **kwargs) -> Response:
180
# Custom template rendering logic
181
template_path = f"{self.template_dir}/{template_name}"
182
183
with open(template_path, 'r') as file:
184
content = file.read()
185
186
# Simple variable substitution (example)
187
for key, value in kwargs.items():
188
content = content.replace(f"{{{key}}}", str(value))
189
190
return Response(
191
status_code=status_codes.HTTP_200_OK,
192
description=content,
193
headers=Headers({"Content-Type": "text/html; charset=utf-8"})
194
)
195
196
app = Robyn(__file__)
197
custom_templates = CustomTemplateEngine("./custom_templates")
198
199
@app.get("/custom")
200
def custom_page(request):
201
return custom_templates.render_template(
202
"page.html",
203
title="Custom Template",
204
content="This uses a custom template engine"
205
)
206
207
app.start()
208
```
209
210
### Error Handling
211
212
```python
213
from robyn import Robyn, status_codes
214
from robyn.templating import JinjaTemplate
215
from jinja2 import TemplateNotFound
216
217
app = Robyn(__file__)
218
templates = JinjaTemplate("./templates")
219
220
@app.get("/safe-render/<template_name>")
221
def safe_render(request):
222
template_name = request.path_params["template_name"]
223
224
try:
225
return templates.render_template(
226
f"{template_name}.html",
227
message="Template rendered successfully"
228
)
229
except TemplateNotFound:
230
return Response(
231
status_code=status_codes.HTTP_404_NOT_FOUND,
232
description="Template not found",
233
headers={}
234
)
235
except Exception as e:
236
return Response(
237
status_code=status_codes.HTTP_500_INTERNAL_SERVER_ERROR,
238
description=f"Template rendering error: {str(e)}",
239
headers={}
240
)
241
242
app.start()
243
```
244
245
### Template Configuration
246
247
```python
248
from robyn import Robyn
249
from robyn.templating import JinjaTemplate
250
251
app = Robyn(__file__)
252
253
# Configure template engine with custom settings
254
templates = JinjaTemplate(
255
directory="./templates",
256
encoding="utf-8",
257
followlinks=False
258
)
259
260
# Templates with conditional rendering
261
@app.get("/dashboard")
262
def dashboard(request):
263
# Check authentication (example)
264
is_authenticated = request.headers.get("Authorization") is not None
265
266
if is_authenticated:
267
return templates.render_template(
268
"dashboard.html",
269
user_name="Current User",
270
notifications=["New message", "System update"],
271
show_admin=True
272
)
273
else:
274
return templates.render_template(
275
"login.html",
276
error_message=None,
277
redirect_url="/dashboard"
278
)
279
280
app.start()
281
```