site is a simple, lightweight static site generator built in Python. It was extracted from my personal blog and designed to be easy to use with clear goals in mind.
Mostly because I'm lazy and got tired of trying to learn other systems like Hugo. But it also comes with very clear goals:
If you have uv installed, you can run commands directly without cloning the repository:
uvx --from git+https://github.com/bradmontgomery/site site inituvx --from git+https://github.com/bradmontgomery/site site builduvx --from git+https://github.com/bradmontgomery/site site newuvx --from git+https://github.com/bradmontgomery/site site serverClone the repository and install dependencies with uv:
$ git clone https://github.com/bradmontgomery/site
$ cd site
$ uv syncThen use commands with uv run:
$ uv run site init # Initialize site structure
$ uv run site build # Build the site
$ uv run site new # Create a new post
$ uv run site server # Run preview serverOrganize your content in the following directory structure:
content/
blog/
<title-slug>/index.md
page/
<title>.mdThe index page should be a listing of recent posts.
Run uvx --from git+https://github.com/bradmontgomery/site site --help for detailed command information:
Usage: site [OPTIONS] COMMAND [ARGS]...
Static site generator.
╭─ Options ────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ --help Show this message and exit. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
╭─ Commands ───────────────────────────────────────────────────────────────────────────────────────────────────────╮
│ build Build the site. │
│ init Initialize a new site structure. │
│ new Create a new blog post. │
│ server Run a local preview HTTP server. │
╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯Blog post dates are stored and transmitted in UTC. When a page loads, a small JavaScript module (timezone.js) converts <time> elements to the reader's local timezone using the browser's Intl.DateTimeFormat API.
Use the Jinja macro for consistent markup:
{% import 'macros/dates.html' as dates %}
{{ dates.local_date(post.date, post.date_iso) }}
{{ dates.local_date(post.date, post.date_iso, format='long') }}
{{ dates.local_date(post.date, post.date_iso, format='date-only') }}If JavaScript is disabled, readers see the UTC fallback text rendered by the server. RSS/Atom feeds are unaffected and continue to use UTC.