Skip to content

qweeze/yahb

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Yet Another Python HTML Builder

A single-file, zero-dependency, fully-typed HTML builder library

Usage:

from yahb import (
    Document,
    Element,
    body,
    h1,
    head,
    html,
    img,
    link,
    main,
    meta,
    p,
    title,
)


def app() -> Element:
    return main(
        h1("Welcome to HTML Builder"),
        p(
            "Here's a cat for you:",
            img(src="https://cataas.com/cat"),
        ),
    )


doc = Document(
    html(
        head(
            meta(charset="UTF-8"),
            meta(name="viewport", content="width=device-width, initial-scale=1.0"),
            title("My Awesome Page"),
            link(rel="stylesheet", href="https://cdn.simplecss.org/simple.css"),
        ),
        body(app()),
        lang="en",
    )
)
print(doc)

Output:

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0"/>
    <title>
      My Awesome Page
    </title>
    <link rel="stylesheet" href="https://cdn.simplecss.org/simple.css"/>
  </head>
  <body>
    <main>
      <h1>
        Welcome to HTML Builder
      </h1>
      <p>
        Here&#x27;s a cat for you:
        <img src="https://cataas.com/cat"/>
      </p>
    </main>
  </body>
</html>

Installation

pip install yahb
# or uv/poetry/pdm/next-shiny-thing add yahb

Features

  • Elements and their attrubutes are parsed from WHATWG site so we have nice IDE / typechecker support:
button(type="circle")
# mypy: Argument "type" to "button" has incompatible type "Literal['circle']";
# expected "Literal['submit', 'reset', 'button']"

a(href=None)
# mypy: Argument "href" to "a" has incompatible type "None"; expected "str"
  • String content is auto-escaped:
print(div("<script>alert('XSS')</script>"))
# <div>&lt;script&gt;alert(&#x27;XSS&#x27;)&lt;/script&gt;</div>
  • Indentation levels support:
print(div("Hello").to_html())
# <div>Hello</div>

print(div("Hello").to_html(indent=4))
# <div>
#     Hello
# </div>

Inspired by

About

Yet another Python HTML builder

Resources

Stars

Watchers

Forks

Packages

No packages published