1
1
# simple_html
2
2
3
- ### Template-less. Type-safe. Minified by default.
3
+ ### Template-less. Type-safe. Minified by default. Fast.
4
4
5
- simple_html is built to simplify HTML rendering in Python. No templates needed. Just create HTML in
6
- normal Python. In most cases, the code will be more concise than standard HTML. Other benefits include:
5
+ simple_html allows you to create HTML in standard Python. Benefits include:
6
+ - typically faster than jinja2 -- up to 15x faster
7
7
- typically renders fewer bytes than template-based rendering
8
- - types mean your editor and tools can help you write correct code faster
9
- - no framework needed
10
- - lightweight
8
+ - types let your editor and tools help you write correct code faster
9
+ - lightweight and framework agnostic
10
+ - always renders valid html
11
11
12
12
13
13
### Installation
@@ -17,82 +17,101 @@ normal Python. In most cases, the code will be more concise than standard HTML.
17
17
### Usage
18
18
19
19
``` python
20
- from simple_html.nodes import body, head, html, p
21
- from simple_html.render import render
22
-
23
- node = html(
24
- head,
25
- body(
26
- p.attrs(id = " hello" )(
27
- " Hello World!"
28
- )
29
- )
30
- )
20
+ from simple_html import div, h1, render, p
21
+
22
+ node = div({},
23
+ h1({" id" : " hello" },
24
+ " Hello World!" ),
25
+ p({},
26
+ " hooray!" ))
27
+
28
+ render(node)
29
+ # <div><h1 id="hello">Hello World!</h1><p>hooray!</p></div>
30
+ ```
31
+
32
+ There are several ways to render nodes:
33
+ ``` python
34
+ from simple_html import br, div, h1, img, render
35
+
36
+ # raw node
37
+ render(br)
38
+ # <br/>
31
39
40
+ # node with attributes only
41
+ render(img({" src" : " /some/image/url.jpg" , " alt" : " a great picture" }))
42
+ # <img src="/some/image/url.jpg" alt="a great picture"/>
43
+
44
+ # node with children
32
45
render(
33
- node) # returns: <html><head></head><body><p id="hello">Hello World!</p></body></html>
46
+ div({},
47
+ h1({},
48
+ " something" ))
49
+ )
50
+ # <div><h1>something</h1></div>'
34
51
```
35
52
53
+ Tag attributes with ` None ` as the value will only render the attribute name:
54
+ ``` python
55
+ from simple_html import div, render
56
+
57
+ render(
58
+ div({" empty-str-attribute" : " " ,
59
+ " key-only-attr" : None })
60
+ )
61
+ # <div empty-str-attribute="" key-only-attr></div>
62
+ ```
36
63
37
64
Strings are escaped by default, but you can pass in ` SafeString ` s to avoid escaping.
38
65
39
66
``` python
40
- from simple_html.nodes import br, p, safe_string
41
- from simple_html.render import render
67
+ from simple_html import br, p, SafeString, render
42
68
43
- node = p(
44
- " Escaped & stuff" ,
45
- br,
46
- safe_string(" Not escaped & stuff" )
47
- )
69
+ node = p({},
70
+ " Escaped & stuff" ,
71
+ br,
72
+ SafeString(" Not escaped & stuff" ))
48
73
49
74
render(node) # returns: <p>Escaped & stuff<br/>Not escaped & stuff</p>
50
75
```
51
76
52
- For convenience, many tags are provided, but you can create your own as well:
53
-
77
+ Lists and generators are both valid collections of nodes:
54
78
``` python
55
- from simple_html.nodes import Tag
56
- from simple_html.render import render
79
+ from typing import Generator
80
+ from simple_html import div, render, Node, br
57
81
58
- custom_elem = Tag(" custom-elem" )
59
82
60
- render(
61
- custom_elem.attrs(id = " some-custom-elem-id" )(
62
- " Wow"
63
- )
64
- ) # returns: <custom-elem id="some-custom-elem-id">Wow</custom-elem>
65
- ```
83
+ def get_list_of_nodes () -> list[Node]:
84
+ return [" neat" , br]
66
85
67
- Likewise, some attributes have been created as type-safe presets. Note that there are multiple ways to create attributes.
68
- The examples below are all equivalent:
69
86
70
- ``` python
71
- from simple_html.attributes import height, id_
72
- from simple_html.nodes import div
87
+ render(div({}, get_list_of_nodes()))
88
+ # <div>neat<br/></div>
73
89
74
90
75
- # **kwargs: recommended for most cases
76
- div.attrs(id = " some-id" , height = " 100" )
91
+ def node_generator () -> Generator[Node, None , None ]:
92
+ yield " neat"
93
+ yield br
77
94
78
- # *args: useful for attributes that may be reserved keywords or when type constraints are desired.
79
- # Presets, raw tuples, and kwargs can be used interchangeably.
80
- div.attrs(id_(" some-id" ),
81
- height(100 ),
82
- (" class" , " abc" ),
83
- width = " 100" )
84
95
85
- # renders to: <div id="some-id" height="100" class="abc" width="100"></div>
96
+ render(
97
+ div({}, node_generator())
98
+ )
99
+ # <div>neat<br/></div>
86
100
```
87
101
88
- You can build your own presets, using ` str_attr ` , ` int_attr ` , or ` bool_attr ` . For instance, here are
89
- several of the attribute preset definitions
102
+
103
+ For convenience, many tags are provided, but you can also create your own:
90
104
91
105
``` python
92
- from simple_html.attributes import bool_attr, int_attr, str_attr
106
+ from simple_html import Tag, render
107
+
108
+ custom_elem = Tag(" custom-elem" )
109
+
110
+ # works the same as any other tag
111
+ node = custom_elem(
112
+ {" id" : " some-custom-elem-id" },
113
+ " Wow"
114
+ )
93
115
94
- checked = bool_attr(' checked' )
95
- class_ = str_attr(' class' )
96
- cols = int_attr(' cols' )
116
+ render(node) # <custom-elem id="some-custom-elem-id">Wow</custom-elem>
97
117
```
98
- But anything that renders to the type of ` Attribute ` will work.
0 commit comments