minihtmlΒΆ
minihtml
is a library to generate HTML documents from Python. It aims to
provide an API that allows you to define the structure of an HTML document in a
succinct and natural way.
By building up nested HTML elements using context managers, you can combine HTML generation with control flow statements in a way that is easy to read and does not obscure the structure of the resulting HTML document.
For example, this code:
from minihtml.tags import a, body, div, head, html, img, li, p, title, ul
links = [("Home", "/"), ("About Me", "/about"), ("Projects", "/projects")]
with html(lang="en") as elem:
with head:
title("hello, world!")
with body, div["#content main"]:
p("Welcome to ", a(href="https://example.com/")("my website"))
img(src="hello.png", alt="hello")
with ul:
for title, url in links:
li(a(href=url)(title))
print(elem)
produces this HTML:
<html lang="en">
<head>
<title>hello, world!</title>
</head>
<body>
<div id="content" class="main">
<p>Welcome to <a href="https://example.com/">my website</a></p>
<img src="hello.png" alt="hello">
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about">About Me</a></li>
<li><a href="/projects">Projects</a></li>
</ul>
</div>
</body>
</html>
The short example above already shows a few key features of the API:
declarative API: Using the declarative style, you can use regular
for
loops and other control flow statements to build up nested elements:>>> from minihtml.tags import ul, li >>> with ul as ingredients: ... for item in ("bacon", "lettuce", "tomato"): ... li(item) <...> >>> print(ingredients) <ul> <li>bacon</li> <li>lettuce</li> <li>tomato</li> </ul>
You can also use a list comprehension of course, but this tends to only work for very simple examples. As soon as you start nesting loops or have inline conditionals, readability suffers.
>>> ingredients = ul(*[li(item) for item in ("bacon", "lettuce", "tomato")]) >>> print(ingredients) <ul> <li>bacon</li> <li>lettuce</li> <li>tomato</li> </ul>
fluent API: Operations on elements can be chained to write code that is close to the generated HTML:
>>> from minihtml.tags import a >>> link = a(href="http://example.com/")("My Website") >>> print(link) <a href="http://example.com/">My Website</a>
shortcuts: There are convenient shortcuts to set the common HTML attributes id and class:
>>> from minihtml.tags import div >>> content = div["#content text-xl font-bold"] >>> print(content) <div id="content" class="text-xl font-bold"></div>
pretty printing: All HTML output is pretty-printed (indented) for easier debugging.
Some additional features:
A flexible component system with optional tracking of JS and CSS dependencies.
Helpers for creating re-useable template with layouts.
Comes with type annotations for the entire API (for use with type checkes such as mypy or pyright).
Continue reading at Basics to learn more.