Skip to main content

A purely-functional HTML builder for Python. Think JSX rather than templates.

Project description

htbuilder — tiny HTML string builder for Python

htbuilder lets you build HTML strings using a purely functional syntax in Python. Why use templating languages when you can just use functions?

(PS: If you like this, check out jsbuild which lets you build JavaScript strings by simply annotating Python functions!)

Installation

Just PIP it!

pip install htbuilder

Usage

Just import tags like div with from htbuilder import div, then call them:

# Import any tag you want from htbuilder, and it just works!
# (This syntax requires Python 3.7+. See below for an alternate syntax)
from htbuilder import div

dom = div('Hello world!')

Then you can get the string output by calling str() on it:

str(dom)
# Returns '<div>Hello world!</div>'

...which means you can also just print() to see it in the terminal:

print(dom)
# Prints '<div>Hello world!</div>'

To specify attributes, call the tag builder with keyword args:

print(
  div(id='sidebar', foo='bar')
)
# Prints '<div id="sidebar" foo="bar"></div>'

To specify both attributes and children, first specify the attributes using keyword args, then pass the children afterwards inside a new set of parentheses:

print(
  div(id='sidebar', foo='bar')(
    "Hello world!"
  )
)
# Prints '<div id="sidebar" foo="bar">Hello world!</div>'

This is required because Python doesn't allow you to pass keyword arguments before you pass normal arguments.

Multiple children

Want to output multiple children? Just pass them all as arguments:

from htbuilder import div, ul, li, img

dom = (
  div(id='container')(
    ul(_class='greetings')(
      li('hello'),
      li('hi'),
      li('whattup'),
    )
  )
)

print(dom)

# Prints this (but without added spacing):
# <div id="container">
#   <ul class="greetings">
#     <li>hello</li>
#     <li>hi</li>
#     <li>whattup</li>
#   </ul>
# </div>

Programmatically add children

You can also pass any iterable to specify multiple children, which means you can simply use things like generator expressions for great awesome:

from htbuilder import div, ul, li, img

image_paths = [
  'http://myimages.com/foo1.jpg',
  'http://myimages.com/foo2.jpg',
  'http://myimages.com/foo3.jpg',
]

dom = (
  div(id='container')(
    ul(_class='image-list')(
      li(img(src=image_path, _class='large-image'))
      for image_path in image_paths
    )
  )
)

print(dom)
# Prints:
# <div id="container">
#   <ul class="image-list">
#     <li><img src="http://myimages.com/foo1.jpg" class="large-image"/></li>
#     <li><img src="http://myimages.com/foo2.jpg" class="large-image"/></li>
#     <li><img src="http://myimages.com/foo3.jpg" class="large-image"/></li>
#   </ul>
# </div>

Conditionally add elements

And because it's just Python, you can use an if/else expression to conditionally insert elements:

use_bold = True

dom = (
  div(
      b("bold text")
    if use_bold else
      "normal text"
  )
)

print(dom)
# Prints: <div><b>bold text</b></div>

Styling

We provide helpers to write styles without having to pass huge style strings as arguments. Instead, just use handy builders like styles(), classes(), fonts(), along with helpers you can import from the units and funcs modules.

# styles, classes, and fonts are special imports to help build attribute strings.
from htbuilder import div, styles, classes, fonts

# You can import anything from .units and .funcs to make it easier to specify
# units like "%" and "px", as well as functions like "rgba()" and "rgba()".
from htbuilder.units import percent, px
from htbuilder.funcs import rgba, rgb

bottom_margin = 10
is_big = True

dom = (
  div(
    _class=classes('btn', big=is_big)
    style=styles(
        color='black',
        font_family=fonts('Comic Sans', 'sans-serif'),
        margin=px(0, 0, bottom_margin, 0),
        padding=(px(10), percent(5))
        box_shadow=[
            (0, 0, px(10), rgba(0, 0, 0, 0.1)),
            (0, 0, '2px', rgb(0, 0, 0)),
        ],
    )
  )
)

# Prints:
# <div
#   class="btn big"
#   style="
#     color: black;
#     font-family: "Comic Sans", "sans-serif";
#     margin: 0 0 10px 0;
#     padding: 10px 5%;
#     box-shadow: 0 0 10px rgba(0, 0, 0, 0.1), 0 0 2px rgb(0, 0, 0);
#   "></div>

Underscores are magic

Use underscores instead of dashes

Like most popular languages, Python doesn't support dashes in identifiers. So if you want to build an element that includes dashes in the tag name or attributes, like <my-element foo-bar="baz">, you can do so by using underscores instead:

from htbuilder import my_element

dom = my_element(foo_bar="baz")

print(dom)
# Prints:
# <my-element foo-bar="baz"></my-element>

Prefix with underscore to avoid reserved words

The word class is reserved in Python, so if you want to set an element's class attribute you should prepend it with an underscore like this:

dom = div(_class="myclass")

print(dom)
# Prints:
# <div class="myclass"></div>

This works because underscores preceding or following any identifier are automatically stripped away for you.

Working with Python < 3.7

If using Python < 3.7, the import should look like this instead:

from htbuilder import H

div = H.div
ul = H.ul
li = H.li
img = H.img
# ...etc

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

htbuilder-0.6.2.tar.gz (10.1 kB view details)

Uploaded Source

Built Distribution

htbuilder-0.6.2-py3-none-any.whl (12.4 kB view details)

Uploaded Python 3

File details

Details for the file htbuilder-0.6.2.tar.gz.

File metadata

  • Download URL: htbuilder-0.6.2.tar.gz
  • Upload date:
  • Size: 10.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.5

File hashes

Hashes for htbuilder-0.6.2.tar.gz
Algorithm Hash digest
SHA256 9979a4fb6e50ce732bf6f6bc0441039dcaa3a3fc70689d8f38f601ed8a1aeec0
MD5 f23d7e84935256570eb3922cbb7d8d9d
BLAKE2b-256 e0cf337b4d0d9502ec72eab7cfc65cde55f007355b090b259573e2fb1cb4e086

See more details on using hashes here.

Provenance

File details

Details for the file htbuilder-0.6.2-py3-none-any.whl.

File metadata

  • Download URL: htbuilder-0.6.2-py3-none-any.whl
  • Upload date:
  • Size: 12.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.5

File hashes

Hashes for htbuilder-0.6.2-py3-none-any.whl
Algorithm Hash digest
SHA256 5bb707221a0e2162e406c9ecf7bcc9efa9ad590c9f2180149440415f43a10bb5
MD5 1f0eac58c736f707c7964c1334c9e1bb
BLAKE2b-256 77cc51b3d514162a648c62d68bcace87be71ca4a49e75dd4959affde27ff386f

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page