nate makes generating HTML fun. Rather than forcing you to adopt an entirely different templating language that comes with its own set of quirks, nate is built around a simple, but powerful Python DSL that enables you to easily compose trees of elements that can be translated to well-formed HTML - no more forgotten angle brackets, unbalanced tags, or unescaped user input.
Think of nate as an alternative to Jinja or Django templates.
With pip installed, run
$ pip install nate
Import the elements you need.
from nate import Table, Thead, Th, Tr, Tbody, Td
Construct your tree.
politicians = [
{"first_name": "Theodor", "last_name": "Heuss", "party": "FDP"},
{"first_name": "Heinrich", "last_name": "Lübke", "party": "CDU"},
{"first_name": "Gustav", "last_name": "Heinemann", "party": "SPD"},
# ...
]
table = Table(
[
Thead(Th([Tr("First Name"), Tr("Last Name"), Tr("Party")])),
Tbody(map(
lambda politician: Tr(
[
Td(politician["first_name"]),
Td(politician["last_name"]),
Td(politician["party"]),
]
),
politicians,
)),
]
)
Call .to_html()
on your root node to serialize your tree to a string of HTML.
table.to_html() #=> <table><thead>....
Raw text nodes are escaped by default, thus making it difficult to introduce XSS vulnerabilities.
p = P("<script>alert('XSS');</script>")
p.to_html() #=> <p><script>alert('XSS');</script></p>
Templating languages tend to come with their own abstractions for building re-usable components. There is no need for those in nate, given that component hierarchies can easily be composed using plain Python functions.
from nate import Div, H1, P, BaseTag
def MyComponent(title: str, description: str) -> BaseTag:
return Div(
children=[
H1(title),
P(description),
],
class_="my-component",
)
component = MyComponent(
title="My title",
description="My description",
)
component.to_html() #=> <div class="my-component>...
Title("Hello World!").to_html()
<title>Hello World!</title>
steaks = ["Rib Eye", "New York Strip", "Porterhouse"]
Ul(map(lambda steak: Li(steak), steaks)).to_html()
<ul>
<li>Rib Eye</li>
<li>New York Strip</li>
<li>Porterhouse</li>
</ul>
Html(
lang="en",
children=[
Head(
children=[
Meta(charset="utf-8"),
Title(children="Welcome to nate!"),
]
),
Body(
children=[
H1("Mission"),
P(
"nate is not a template engine.",
class_="red",
),
],
),
],
).to_html()
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8"/>
<title>Welcome to nate!</title>
</head>
<body>
<h1>Mission</h1>
<p class="red">nate is not a template engine.</p>
</body>
</html>
page.rb
library inspired this project.MIT