htmlforge
Build web pages with Python, export to HTML with a single command — like manim generates videos.
manim scene.py MyScene → mp4
htmlforge page.py MyPage → html
Installation
pip install htmlforge
Development install:
pip install -e ".[dev]"
Quick Start
1. Write a Python page script mysite.py
from htmlforge import Doc
page = Doc("My Site")
# Generate styles with Python code (no CSS needed!)
page.style("body", background="#f5f5f5", font_family="sans-serif")
page.style(".py-card", border_radius="12px", box_shadow="0 2px 8px rgba(0,0,0,.1)")
# Build the page
page.heading("Welcome to My Site")
page.text("Built with **htmlforge**, supports *Markdown* syntax")
page.card("Features",
"40+ HTML components",
"Generate styles with Python code",
"Export HTML with one command",
)
page.table(
["Feature", "Description"],
[
["Components", "40+ HTML components"],
["Built-in theme", "Works out of the box"],
["CLI tools", "render / serve / watch"],
],
)
page.button("Click me", on_click="alert('Hello!')", color="#4CAF50")
2. Run the command to export HTML
# Basic render
htmlforge render mysite.py
# Specify output directory
htmlforge render mysite.py -o build
# Render and start a local server
htmlforge render mysite.py -s
# Watch for file changes and auto-rebuild
htmlforge render mysite.py -w
# Render a specific page (when file has multiple pages)
htmlforge render mysite.py MyPage
CLI Commands
| Command | Description |
|---|---|
htmlforge render <file.py> |
Render all pages to dist/ |
htmlforge render <file.py> -o <dir> |
Specify output directory |
htmlforge render <file.py> <page> |
Render only the specified page |
htmlforge render <file.py> -s |
Start HTTP server after render |
htmlforge render <file.py> -s -p 3000 |
Specify server port |
htmlforge render <file.py> -w |
Watch for changes and auto-rebuild |
Doc API — Ultra Simple
Doc is a high-level API designed for Python programmers who don't know HTML. It comes with a built-in theme — no CSS required to build great-looking pages.
from htmlforge import Doc
page = Doc("Title")
# Generate styles with Python kwargs (no CSS strings!)
page.style("body", background="linear-gradient(135deg, #667eea, #764ba2)", color="white")
page.style("h1", font_size="3rem", text_align="center")
page.style(".py-card", background="rgba(255,255,255,.15)", backdrop_filter="blur(10px)")
# Content (supports **Markdown** syntax)
page.heading("Hello World")
page.text("Supports **bold**, *italic*, `code`, [links](url)")
page.card("Card Title", "Card content, **supports Markdown**")
page.list(["Item A", "Item B", "Item C"])
page.table(["Col 1", "Col 2"], [["a", "b"], ["c", "d"]])
page.button("Button", on_click="alert('hi')", color="#e74c3c")
page.input("Type here...", name="name")
page.select(["Option A", "Option B", "Option C"])
page.code("print('hello')", lang="python")
page.details("Collapsible", "Hidden content...")
page.nav(("Home", "/"), ("About", "/about"))
page.divider()
# Layout
page.row(Doc.make_card("A"), Doc.make_card("B"), Doc.make_card("C"))
Page API — Fine-grained Control
Use Page + the component system when you need more control:
from htmlforge import Page, H1, P, Div, Table, Button
page = Page("Title", lang="en")
page.add_css("body { font-family: sans-serif; }")
page.add(
H1("Welcome"),
P("Hello World"),
Div(class_="card").add(
H1("Features", level=2),
P("Content..."),
),
)
Element — Chainable API
div = Div(id="main", class_="wrapper")
div.add(H1("Title"), P("Content")) # Add child elements
div.css(color="red", font_size="16px") # Set inline styles (camelCase → kebab-case)
div.attr("data-id", "123") # Set attributes
html = div.render() # → HTML string
Components
| Category | Components |
|---|---|
| Structure | Div, Section, Header, Footer, Nav, Main, Article, Aside, Span, Container |
| Text | H1-H6, P, Strong, Em, Blockquote, Code, Pre, Small, Mark |
| Links/Media | Link, Img, Video, Audio, Iframe, Canvas |
| Lists | Ul, Ol, Li, List |
| Tables | Table, Thead, Tbody, Tr, Th, Td, Caption |
| Forms | Form, Input, Textarea, Select, Option, Checkbox, Radio, Label, Button |
| Other | Hr, Br, Text, Progress, Details, Summary |
Example: Multi-page Site
# site.py
from htmlforge import Doc
home = Doc("Home")
home.heading("Home")
home.text("Welcome to the home page")
about = Doc("About")
about.heading("About Us")
about.text("This is the about page")
blog = Doc("Blog")
blog.heading("Blog")
blog.text("Latest posts...")
htmlforge render site.py
# → dist/home.html, dist/about.html, dist/blog.html
License
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
htmlforge-0.0.1.tar.gz
(20.1 kB
view details)
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
htmlforge-0.0.1-py3-none-any.whl
(14.7 kB
view details)
File details
Details for the file htmlforge-0.0.1.tar.gz.
File metadata
- Download URL: htmlforge-0.0.1.tar.gz
- Upload date:
- Size: 20.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
487998410369e81f53f74df783e22c586245c1137eb76cc67611a8f395066f86
|
|
| MD5 |
dc6af9fafa8364e9932a07c4a33d442a
|
|
| BLAKE2b-256 |
2094d6ebfdb457c16c3903b656755338c593cee5f221cd0c3d63902d2d402aed
|
File details
Details for the file htmlforge-0.0.1-py3-none-any.whl.
File metadata
- Download URL: htmlforge-0.0.1-py3-none-any.whl
- Upload date:
- Size: 14.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.11.8
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
11253ceb8d568ea067ccfcdfc4cd6b89e15a30ad7258dab509c3516b7df5f6c7
|
|
| MD5 |
8aa8f3448e51bf525af95c91ff060288
|
|
| BLAKE2b-256 |
5d432c69a0dfe16a0e12811c1625ceb653c2e00dad52a81f21cf41dde5e6327d
|