0
# HTML System
1
2
Comprehensive HTML element system with 60+ node classes covering all HTML5 elements, plus utilities for HTML parsing and document building. All HTML elements support event handling, real-time DOM updates, and automatic synchronization between Python objects and the browser DOM.
3
4
## Capabilities
5
6
### HTML Document Builder
7
8
Core function for creating HTML documents and parsing existing HTML content into Python objects.
9
10
```python { .api }
11
def HTML(*args, **kwargs) -> 'Node':
12
"""
13
Create an HTML document or container with child elements.
14
15
Args:
16
*args: Child nodes or text content
17
**kwargs: HTML attributes
18
19
Returns:
20
Node: HTML container node
21
"""
22
23
def parse_html(html_string: str) -> 'Node':
24
"""
25
Parse HTML string into Lona node objects.
26
27
Args:
28
html_string (str): HTML content to parse
29
30
Returns:
31
Node: Parsed HTML as node objects
32
"""
33
```
34
35
#### Usage Example
36
37
```python
38
from lona.html import HTML, H1, P, Div
39
40
# Create HTML structure
41
html = HTML(
42
H1('Welcome to Lona'),
43
P('This is a paragraph with ', Strong('bold text'), '.'),
44
Div(
45
P('Nested content'),
46
id='main-content',
47
class_='container'
48
)
49
)
50
51
# Parse existing HTML
52
from lona.html import parse_html
53
parsed = parse_html('<div><h1>Hello</h1><p>World</p></div>')
54
```
55
56
### Base Node Class
57
58
Foundation class for all HTML elements providing common functionality for content manipulation, attribute handling, and DOM synchronization.
59
60
```python { .api }
61
class Node:
62
def __init__(self, *args, **kwargs):
63
"""
64
Initialize an HTML node.
65
66
Args:
67
*args: Child nodes or text content
68
**kwargs: HTML attributes
69
"""
70
71
def set_text(self, text: str):
72
"""
73
Set the text content of the node.
74
75
Args:
76
text (str): New text content
77
"""
78
79
def get_text(self) -> str:
80
"""
81
Get the text content of the node.
82
83
Returns:
84
str: Current text content
85
"""
86
87
def append(self, *nodes):
88
"""
89
Append child nodes.
90
91
Args:
92
*nodes: Nodes to append
93
"""
94
95
def prepend(self, *nodes):
96
"""
97
Prepend child nodes.
98
99
Args:
100
*nodes: Nodes to prepend
101
"""
102
103
def insert(self, index: int, *nodes):
104
"""
105
Insert nodes at specific index.
106
107
Args:
108
index (int): Position to insert at
109
*nodes: Nodes to insert
110
"""
111
112
def remove(self, *nodes):
113
"""
114
Remove child nodes.
115
116
Args:
117
*nodes: Nodes to remove
118
"""
119
120
def clear(self):
121
"""
122
Remove all child nodes.
123
"""
124
125
def get_attribute(self, name: str):
126
"""
127
Get an HTML attribute value.
128
129
Args:
130
name (str): Attribute name
131
132
Returns:
133
Attribute value or None
134
"""
135
136
def set_attribute(self, name: str, value):
137
"""
138
Set an HTML attribute.
139
140
Args:
141
name (str): Attribute name
142
value: Attribute value
143
"""
144
145
def remove_attribute(self, name: str):
146
"""
147
Remove an HTML attribute.
148
149
Args:
150
name (str): Attribute name to remove
151
"""
152
153
def has_attribute(self, name: str) -> bool:
154
"""
155
Check if node has an attribute.
156
157
Args:
158
name (str): Attribute name
159
160
Returns:
161
bool: True if attribute exists
162
"""
163
164
def add_class(self, class_name: str):
165
"""
166
Add a CSS class.
167
168
Args:
169
class_name (str): Class name to add
170
"""
171
172
def remove_class(self, class_name: str):
173
"""
174
Remove a CSS class.
175
176
Args:
177
class_name (str): Class name to remove
178
"""
179
180
def has_class(self, class_name: str) -> bool:
181
"""
182
Check if node has a CSS class.
183
184
Args:
185
class_name (str): Class name to check
186
187
Returns:
188
bool: True if class exists
189
"""
190
191
def toggle_class(self, class_name: str):
192
"""
193
Toggle a CSS class.
194
195
Args:
196
class_name (str): Class name to toggle
197
"""
198
199
# Properties
200
tag_name: str # HTML tag name
201
attributes: dict # HTML attributes
202
nodes: list # Child nodes
203
parent: 'Node' # Parent node
204
id_: str # Element ID (use underscore to avoid Python keyword)
205
class_: str # CSS classes (use underscore to avoid Python keyword)
206
```
207
208
### Document Structure Elements
209
210
HTML5 document structure elements for organizing page layout and semantics.
211
212
```python { .api }
213
class Html(Node):
214
"""HTML root element."""
215
216
class Head(Node):
217
"""Document head element."""
218
219
class Body(Node):
220
"""Document body element."""
221
222
class Title(Node):
223
"""Document title element."""
224
225
class Meta(Node):
226
"""Meta information element."""
227
228
class Link(Node):
229
"""External resource link element."""
230
231
class Base(Node):
232
"""Document base URL element."""
233
234
class Style(Node):
235
"""CSS style element."""
236
```
237
238
### Content Sectioning Elements
239
240
Elements for organizing and structuring page content into logical sections.
241
242
```python { .api }
243
class H1(Node):
244
"""Level 1 heading."""
245
246
class H2(Node):
247
"""Level 2 heading."""
248
249
class H3(Node):
250
"""Level 3 heading."""
251
252
class H4(Node):
253
"""Level 4 heading."""
254
255
class H5(Node):
256
"""Level 5 heading."""
257
258
class H6(Node):
259
"""Level 6 heading."""
260
261
class Header(Node):
262
"""Page or section header."""
263
264
class Footer(Node):
265
"""Page or section footer."""
266
267
class Nav(Node):
268
"""Navigation section."""
269
270
class Main(Node):
271
"""Main content area."""
272
273
class Section(Node):
274
"""Generic section."""
275
276
class Article(Node):
277
"""Self-contained content."""
278
279
class Aside(Node):
280
"""Sidebar content."""
281
282
class Address(Node):
283
"""Contact information."""
284
285
class HGroup(Node):
286
"""Heading group."""
287
```
288
289
### Text Content Elements
290
291
Elements for organizing and displaying text content, lists, and paragraphs.
292
293
```python { .api }
294
class P(Node):
295
"""Paragraph element."""
296
297
class Div(Node):
298
"""Generic container."""
299
300
class Span(Node):
301
"""Generic inline container."""
302
303
class Ul(Node):
304
"""Unordered list."""
305
306
class Ol(Node):
307
"""Ordered list."""
308
309
class Li(Node):
310
"""List item."""
311
312
class Dl(Node):
313
"""Description list."""
314
315
class Dt(Node):
316
"""Description term."""
317
318
class Dd(Node):
319
"""Description definition."""
320
321
class BlockQuote(Node):
322
"""Block quotation."""
323
324
class Figure(Node):
325
"""Figure with caption."""
326
327
class FigCaption(Node):
328
"""Figure caption."""
329
330
class Hr(Node):
331
"""Horizontal rule."""
332
333
class Pre(Node):
334
"""Preformatted text."""
335
336
class Menu(Node):
337
"""Menu list."""
338
```
339
340
### Inline Semantic Elements
341
342
Elements for adding semantic meaning and formatting to inline text content.
343
344
```python { .api }
345
class A(Node):
346
"""Anchor/link element."""
347
348
class Strong(Node):
349
"""Strong importance."""
350
351
class Em(Node):
352
"""Emphasized text."""
353
354
class B(Node):
355
"""Bold text."""
356
357
class I(Node):
358
"""Italic text."""
359
360
class U(Node):
361
"""Underlined text."""
362
363
class S(Node):
364
"""Strikethrough text."""
365
366
class Mark(Node):
367
"""Highlighted text."""
368
369
class Small(Node):
370
"""Small text."""
371
372
class Sub(Node):
373
"""Subscript."""
374
375
class Sup(Node):
376
"""Superscript."""
377
378
class Code(Node):
379
"""Inline code."""
380
381
class Kbd(Node):
382
"""Keyboard input."""
383
384
class Samp(Node):
385
"""Sample output."""
386
387
class Var(Node):
388
"""Variable."""
389
390
class Time(Node):
391
"""Date/time."""
392
393
class Abbr(Node):
394
"""Abbreviation."""
395
396
class Dfn(Node):
397
"""Definition."""
398
399
class Q(Node):
400
"""Inline quotation."""
401
402
class Cite(Node):
403
"""Citation."""
404
405
class Ruby(Node):
406
"""Ruby annotation."""
407
408
class Rt(Node):
409
"""Ruby text."""
410
411
class Rp(Node):
412
"""Ruby parentheses."""
413
414
class Bdi(Node):
415
"""Bidirectional isolation."""
416
417
class Bdo(Node):
418
"""Bidirectional override."""
419
420
class Wbr(Node):
421
"""Line break opportunity."""
422
423
class Br(Node):
424
"""Line break."""
425
```
426
427
### Form Elements
428
429
Interactive form elements for user input and data collection with built-in event handling.
430
431
```python { .api }
432
class Form(Node):
433
"""HTML form."""
434
435
class Input(Node):
436
"""Generic input element."""
437
438
class TextInput(Node):
439
"""Text input field."""
440
441
class NumberInput(Node):
442
"""Number input field."""
443
444
class TextArea(Node):
445
"""Multi-line text input."""
446
447
class Button(Node):
448
"""Button element."""
449
450
class Select(Node):
451
"""Dropdown selection."""
452
453
class Option(Node):
454
"""Select option."""
455
456
class CheckBox(Node):
457
"""Checkbox input."""
458
459
class RadioButton(Node):
460
"""Radio button input."""
461
462
class RadioGroup(Node):
463
"""Radio button group."""
464
465
class Label(Node):
466
"""Form label."""
467
468
class Fieldset(Node):
469
"""Form field grouping."""
470
471
class Legend(Node):
472
"""Fieldset caption."""
473
474
class Progress(Node):
475
"""Progress indicator."""
476
477
class Meter(Node):
478
"""Measurement gauge."""
479
480
class Output(Node):
481
"""Calculation result."""
482
483
class Datalist(Node):
484
"""Input suggestions."""
485
```
486
487
#### Form Usage Example
488
489
```python
490
from lona.html import HTML, Form, TextInput, Button, Label, CheckBox
491
from lona.events import CHANGE
492
493
@app.route('/form')
494
class FormView(View):
495
def handle_request(self, request):
496
name_input = TextInput(placeholder='Enter your name')
497
email_input = TextInput(type='email', placeholder='Enter your email')
498
subscribe_checkbox = CheckBox()
499
submit_button = Button('Submit', type='submit')
500
501
form = Form(
502
Label('Name:', name_input),
503
Label('Email:', email_input),
504
Label(subscribe_checkbox, ' Subscribe to newsletter'),
505
submit_button
506
)
507
508
self.show(HTML(form))
509
510
# Wait for form submission
511
self.await_click(submit_button)
512
513
# Get form values
514
name = name_input.value
515
email = email_input.value
516
subscribed = subscribe_checkbox.checked
517
518
# Process form data...
519
```
520
521
### Table Elements
522
523
Elements for creating structured tabular data displays.
524
525
```python { .api }
526
class Table(Node):
527
"""HTML table."""
528
529
class THead(Node):
530
"""Table header group."""
531
532
class TBody(Node):
533
"""Table body group."""
534
535
class TFoot(Node):
536
"""Table footer group."""
537
538
class Tr(Node):
539
"""Table row."""
540
541
class Th(Node):
542
"""Table header cell."""
543
544
class Td(Node):
545
"""Table data cell."""
546
547
class Col(Node):
548
"""Table column."""
549
550
class ColGroup(Node):
551
"""Table column group."""
552
553
class Caption(Node):
554
"""Table caption."""
555
```
556
557
#### Table Usage Example
558
559
```python
560
from lona.html import HTML, Table, THead, TBody, Tr, Th, Td
561
562
@app.route('/table')
563
class TableView(View):
564
def handle_request(self, request):
565
table = Table(
566
THead(
567
Tr(Th('Name'), Th('Age'), Th('City'))
568
),
569
TBody(
570
Tr(Td('John'), Td('30'), Td('New York')),
571
Tr(Td('Jane'), Td('25'), Td('London')),
572
Tr(Td('Bob'), Td('35'), Td('Paris'))
573
)
574
)
575
576
return HTML(table)
577
```
578
579
### Media Elements
580
581
Elements for embedding images, audio, video, and other media content.
582
583
```python { .api }
584
class Img(Node):
585
"""Image element."""
586
587
class Audio(Node):
588
"""Audio player."""
589
590
class Video(Node):
591
"""Video player."""
592
593
class Track(Node):
594
"""Media track."""
595
596
class Source(Node):
597
"""Media source."""
598
599
class Canvas(Node):
600
"""Drawing canvas."""
601
```
602
603
#### Media Usage Example
604
605
```python
606
from lona.html import HTML, Img, Video, Source
607
608
@app.route('/media')
609
class MediaView(View):
610
def handle_request(self, request):
611
image = Img(src='/static/photo.jpg', alt='A beautiful photo')
612
613
video = Video(
614
Source(src='/static/video.mp4', type='video/mp4'),
615
Source(src='/static/video.webm', type='video/webm'),
616
controls=True,
617
width=640,
618
height=480
619
)
620
621
return HTML(image, video)
622
```
623
624
### Interactive Elements
625
626
Specialized interactive elements for enhanced user interfaces.
627
628
```python { .api }
629
class Details(Node):
630
"""Collapsible details."""
631
632
class Summary(Node):
633
"""Details summary."""
634
635
class Dialog(Node):
636
"""Modal dialog."""
637
```
638
639
### Widget System
640
641
Base class for creating custom reusable components that combine multiple HTML elements.
642
643
```python { .api }
644
class Widget(Node):
645
"""
646
Base class for custom widgets/components.
647
648
Widgets are reusable components that can encapsulate
649
complex HTML structures and behavior.
650
"""
651
652
def __init__(self, *args, **kwargs):
653
"""
654
Initialize a custom widget.
655
656
Args:
657
*args: Widget arguments
658
**kwargs: Widget keyword arguments
659
"""
660
661
def setup(self):
662
"""
663
Setup method called after widget initialization.
664
Override this to build widget content.
665
"""
666
667
def render(self) -> 'Node':
668
"""
669
Render the widget content.
670
671
Returns:
672
Node: Widget HTML content
673
"""
674
```
675
676
#### Widget Usage Example
677
678
```python
679
from lona.html import Widget, Div, H3, P, Button
680
681
class Alert(Widget):
682
def __init__(self, message, alert_type='info'):
683
self.message = message
684
self.alert_type = alert_type
685
super().__init__()
686
687
def setup(self):
688
close_button = Button('×', class_='close-btn')
689
690
self.nodes = [
691
Div(
692
close_button,
693
H3('Alert'),
694
P(self.message),
695
class_=f'alert alert-{self.alert_type}'
696
)
697
]
698
699
# Usage in view
700
@app.route('/alerts')
701
class AlertView(View):
702
def handle_request(self, request):
703
success_alert = Alert('Operation completed successfully!', 'success')
704
warning_alert = Alert('Please check your input.', 'warning')
705
706
return HTML(success_alert, warning_alert)
707
```
708
709
### HTML Parsing Utilities
710
711
Advanced HTML parsing and manipulation utilities for working with external HTML content.
712
713
```python { .api }
714
class NodeHTMLParser:
715
"""
716
HTML parser class for converting HTML strings to Lona nodes.
717
"""
718
719
def __init__(self):
720
"""Initialize the HTML parser."""
721
722
def feed(self, html_string: str):
723
"""
724
Parse HTML string and return node objects.
725
726
Args:
727
html_string (str): HTML content to parse
728
729
Returns:
730
List of Node objects
731
"""
732
733
def close(self):
734
"""Close the parser and return final results."""
735
```
736
737
### HTML Constants and Utilities
738
739
Constants and utility collections used throughout the HTML system.
740
741
```python { .api }
742
# Node class mappings
743
NODE_CLASSES: dict # Maps HTML tag names to node classes
744
745
# Input element mappings
746
INPUT_NODE_CLASSES: dict # Maps input types to input node classes
747
748
# Self-closing HTML tags
749
SELF_CLOSING_TAGS: list # List of self-closing HTML tag names
750
751
# Utility constants
752
VOID_ELEMENTS: set # HTML void elements that cannot have content
753
BOOLEAN_ATTRIBUTES: set # HTML boolean attributes
754
```
755
756
## Types
757
758
```python { .api }
759
from typing import Union, Optional, Dict, List, Any
760
761
# Node content types
762
NodeContent = Union[str, int, float, 'Node']
763
HTMLContent = Union[NodeContent, List[NodeContent]]
764
AttributeValue = Union[str, int, float, bool, None]
765
AttributeDict = Dict[str, AttributeValue]
766
767
# HTML parsing types
768
HTMLString = str
769
ParsedNodes = List['Node']
770
771
# Widget types
772
WidgetArgs = tuple
773
WidgetKwargs = Dict[str, Any]
774
```