0
# Utilities
1
2
Text processing utilities for HTML escaping, URL encoding, raw HTML insertion, file inclusion, and specialized container elements for advanced layouts.
3
4
## Capabilities
5
6
### Text Processing
7
8
HTML and URL encoding/decoding utilities for safe content handling.
9
10
```python { .api }
11
def escape(data, quote=True):
12
"""
13
Escape special characters for HTML content.
14
15
Parameters:
16
- data (str): Text to escape
17
- quote (bool): Whether to escape quote characters
18
19
Returns:
20
- str: HTML-escaped text
21
22
Escapes: & < > and optionally "
23
"""
24
25
def unescape(data):
26
"""
27
Unescape HTML entities back to original characters.
28
29
Parameters:
30
- data (str): HTML-escaped text
31
32
Returns:
33
- str: Unescaped text
34
"""
35
36
def url_escape(data):
37
"""
38
URL-encode special characters.
39
40
Parameters:
41
- data (str): Text to URL-encode
42
43
Returns:
44
- str: URL-encoded text
45
"""
46
47
def url_unescape(data):
48
"""
49
Decode URL-encoded characters.
50
51
Parameters:
52
- data (str): URL-encoded text
53
54
Returns:
55
- str: Decoded text
56
"""
57
```
58
59
#### Usage Examples
60
61
```python
62
from dominate.util import escape, unescape, url_escape, url_unescape
63
64
# HTML escaping
65
user_input = '<script>alert("XSS")</script>'
66
safe_html = escape(user_input)
67
# Result: '<script>alert("XSS")</script>'
68
69
# HTML unescaping
70
escaped_text = '<b>Bold</b>'
71
original = unescape(escaped_text)
72
# Result: '<b>Bold</b>'
73
74
# URL encoding
75
search_query = 'hello world & more'
76
encoded = url_escape(search_query)
77
# Result: 'hello%20world%20%26%20more'
78
79
# URL decoding
80
encoded_url = 'hello%20world%20%26%20more'
81
decoded = url_unescape(encoded_url)
82
# Result: 'hello world & more'
83
84
# Quote handling
85
text_with_quotes = 'Say "hello" to the world'
86
escaped_no_quotes = escape(text_with_quotes, quote=False)
87
# Result: 'Say "hello" to the world' (quotes not escaped)
88
escaped_with_quotes = escape(text_with_quotes, quote=True)
89
# Result: 'Say "hello" to the world'
90
```
91
92
### Raw Content Insertion
93
94
Insert unescaped HTML content and include external files.
95
96
```python { .api }
97
def raw(s):
98
"""
99
Insert raw HTML without escaping.
100
101
Parameters:
102
- s (str): Raw HTML string
103
104
Returns:
105
- text: Text element with escaping disabled
106
107
Warning: Use carefully to avoid XSS vulnerabilities
108
"""
109
110
def include(f):
111
"""
112
Include contents of a file as raw HTML.
113
114
Parameters:
115
- f (str): File path to include
116
117
Returns:
118
- text: Text element containing file contents
119
"""
120
```
121
122
#### Usage Examples
123
124
```python
125
from dominate.util import raw, include
126
from dominate.tags import div, p
127
128
# Raw HTML insertion
129
container = div(
130
p('Regular paragraph'),
131
raw('<em>This HTML will not be escaped</em>'),
132
p('Another regular paragraph')
133
)
134
135
# Including external files
136
# Assuming 'snippet.html' contains: '<b>Bold content</b>'
137
content = div(
138
h2('Included Content'),
139
include('snippet.html') # File contents inserted as-is
140
)
141
142
# Combining with other elements
143
mixed_content = div(
144
h1('Page Title'),
145
raw('''
146
<div class="custom-widget">
147
<p>This is raw HTML with custom styling</p>
148
<button onclick="customFunction()">Click Me</button>
149
</div>
150
'''),
151
p('Back to regular content')
152
)
153
```
154
155
### System Command Execution
156
157
Execute system commands and capture output for dynamic content generation.
158
159
```python { .api }
160
def system(cmd, data=None):
161
"""
162
Execute system command and return output.
163
164
Parameters:
165
- cmd (str): Command to execute
166
- data (str|None): Optional input data to pipe to command
167
168
Returns:
169
- str: Command output (decoded as UTF-8)
170
"""
171
```
172
173
#### Usage Example
174
175
```python
176
from dominate.util import system, raw
177
from dominate.tags import div, h2, pre
178
179
# Execute command and include output
180
container = div(
181
h2('System Information'),
182
pre(system('date')), # Current date/time
183
h2('Directory Listing'),
184
pre(system('ls -la')) # Directory contents
185
)
186
187
# Process markdown with external tool
188
markdown_content = "# Hello\n\nThis is **markdown**."
189
html_output = system('markdown', data=markdown_content)
190
content = div(raw(html_output))
191
```
192
193
### Specialized Container Elements
194
195
Container elements for advanced layout control and content organization.
196
197
```python { .api }
198
class container(dom_tag):
199
"""
200
Invisible container that groups elements without adding HTML structure.
201
202
Properties:
203
- is_inline = True: Renders children inline without wrapper element
204
"""
205
206
def _render(self, sb, indent_level, indent_str, pretty, xhtml):
207
"""Custom rendering that outputs only children, no wrapper element."""
208
209
class text(dom_tag):
210
"""
211
Text node element for inserting plain or raw text content.
212
213
Properties:
214
- is_pretty = False: No pretty printing
215
- is_inline = True: Inline rendering
216
"""
217
218
def __init__(self, _text, escape=True):
219
"""
220
Create text node.
221
222
Parameters:
223
- _text (str): Text content
224
- escape (bool): Whether to HTML-escape the text
225
"""
226
227
@property
228
def escape(self) -> bool:
229
"""Whether text is HTML-escaped."""
230
231
class lazy(dom_tag):
232
"""
233
Lazy evaluation container that delays function execution until rendering.
234
"""
235
236
def __init__(self, func, *args, **kwargs):
237
"""
238
Create lazy evaluation element.
239
240
Parameters:
241
- func (callable): Function to execute during rendering
242
- *args: Arguments for the function
243
- **kwargs: Keyword arguments for the function
244
"""
245
246
@property
247
def func(self) -> callable:
248
"""Function to execute."""
249
250
@property
251
def args(self) -> tuple:
252
"""Function arguments."""
253
254
@property
255
def kwargs(self) -> dict:
256
"""Function keyword arguments."""
257
```
258
259
#### Usage Examples
260
261
```python
262
from dominate.util import container, text, lazy
263
from dominate.tags import div, p, ul, li
264
265
# Container for grouping without HTML wrapper
266
page_content = div(
267
h1('Page Title'),
268
container(
269
# These elements will be added directly to the div,
270
# not wrapped in another element
271
p('First paragraph'),
272
p('Second paragraph'),
273
ul(li('Item 1'), li('Item 2'))
274
),
275
p('Footer paragraph')
276
)
277
278
# Text nodes with different escaping
279
content = div(
280
text('This will be escaped: <b>bold</b>', escape=True),
281
text('This will NOT be escaped: <b>bold</b>', escape=False)
282
)
283
284
# Using text in context managers
285
with div() as container:
286
text('Start of content ')
287
a('link text', href='/link')
288
text(' end of content.')
289
290
# Lazy evaluation for dynamic content
291
def get_current_time():
292
import datetime
293
return datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')
294
295
def generate_user_list():
296
users = ['Alice', 'Bob', 'Charlie']
297
return ul([li(user) for user in users])
298
299
page = div(
300
h1('Dynamic Content'),
301
p('Current time: ', lazy(get_current_time)),
302
h2('User List'),
303
lazy(generate_user_list)
304
)
305
306
# Lazy with arguments
307
def format_price(amount, currency='USD'):
308
return f'{amount} {currency}'
309
310
product = div(
311
h3('Product Name'),
312
p('Price: ', lazy(format_price, 29.99, currency='EUR'))
313
)
314
```
315
316
### Advanced Text Handling
317
318
Complex text processing and content management utilities.
319
320
#### Text Element with Context Manager
321
322
```python
323
# Text elements in context managers
324
with p() as paragraph:
325
text('Have a look at our ')
326
a('other products', href='/products')
327
text(' for more options.')
328
329
# Result: <p>Have a look at our <a href="/products">other products</a> for more options.</p>
330
```
331
332
#### Container for Complex Layouts
333
334
```python
335
# Advanced container usage
336
def create_card_layout(title, content, actions):
337
return container(
338
div(h3(title), cls='card-header'),
339
div(p(content), cls='card-body'),
340
div(actions, cls='card-footer')
341
)
342
343
# Use in larger structure
344
page = div(
345
create_card_layout(
346
'Welcome',
347
'This is the welcome message.',
348
[button('Get Started'), button('Learn More')]
349
),
350
create_card_layout(
351
'Features',
352
'Here are the key features.',
353
button('View All Features')
354
),
355
cls='card-container'
356
)
357
```
358
359
#### Lazy Evaluation Patterns
360
361
```python
362
# Conditional lazy evaluation
363
def maybe_show_admin_panel(user):
364
if user.is_admin:
365
return div(
366
h2('Admin Panel'),
367
button('Manage Users'),
368
button('View Analytics')
369
)
370
return ''
371
372
# Database-driven content
373
def load_recent_posts():
374
# Simulated database call
375
posts = get_recent_posts_from_db()
376
return div([
377
article(
378
h3(post.title),
379
p(post.excerpt)
380
) for post in posts
381
])
382
383
# Template with lazy sections
384
template = div(
385
header(h1('My Blog')),
386
main(lazy(load_recent_posts)),
387
aside(lazy(maybe_show_admin_panel, current_user)),
388
footer('© 2023 My Blog')
389
)
390
```
391
392
## Complete Utility Example
393
394
```python
395
from dominate import document
396
from dominate.tags import *
397
from dominate.util import *
398
import datetime
399
400
def create_dynamic_page():
401
"""Create a page with various utility features."""
402
403
# Dynamic content functions
404
def current_stats():
405
return container(
406
p(f'Generated at: {datetime.datetime.now()}'),
407
p(f'System uptime: {system("uptime")}')
408
)
409
410
def load_external_content():
411
# Simulate loading from external source
412
return raw('''
413
<div class="external-widget">
414
<h4>External Content</h4>
415
<p>This content was loaded from an external source.</p>
416
</div>
417
''')
418
419
# Build page
420
doc = document(title='Utility Demo')
421
422
with doc.head:
423
style('''
424
.highlight { background-color: yellow; }
425
.external-widget { border: 1px solid #ccc; padding: 10px; }
426
''')
427
428
with doc:
429
header(
430
h1('Dominate Utilities Demo'),
431
nav(
432
container(
433
a('Home', href='/'),
434
text(' | '),
435
a('About', href='/about'),
436
text(' | '),
437
a('Contact', href='/contact')
438
)
439
)
440
)
441
442
main(
443
section(
444
h2('Text Processing'),
445
p('User input: ', code(escape('<script>alert("safe")</script>'))),
446
p('URL example: ', code(url_escape('hello world & more')))
447
),
448
449
section(
450
h2('Dynamic Content'),
451
lazy(current_stats)
452
),
453
454
section(
455
h2('External Content'),
456
lazy(load_external_content)
457
),
458
459
section(
460
h2('Raw HTML'),
461
raw('<p class="highlight">This HTML is not escaped</p>')
462
)
463
)
464
465
footer(
466
container(
467
text('© 2023 Demo Site | '),
468
a('Privacy Policy', href='/privacy'),
469
text(' | '),
470
a('Terms of Service', href='/terms')
471
)
472
)
473
474
return doc
475
476
# Generate and output the page
477
page = create_dynamic_page()
478
print(page)
479
```