-
Notifications
You must be signed in to change notification settings - Fork 0
Project Structure
The Fifty repo is a monorepo: each theme is a top-level subdirectory, all shared tooling lives in bin/, and there is no per-theme node_modules, no per-theme build output, and no per-theme package.json.
fifty/
├── obel/ # base theme (the reference implementation — read first)
├── chonk/ # neo-brutalist variant
├── selvedge/ # workwear / indigo variant
├── lysholm/ # Nordic home goods variant
├── bin/ # shared CLI tooling (run from the monorepo root)
├── playground/ # shared Playground PHP helpers (see playground/AGENTS.md)
├── docs/ # generated GH Pages site of short URLs (see bin/build-redirects.py)
├── tests/ # committed visual-regression baselines (PNG)
├── tmp/ # gitignored: snap output, playground server logs, blueprint scratch
├── AGENTS.md # repo-root agent guide (every footgun + guardrail in one file)
├── README.md # the elevator pitch and the live demo links
├── LICENSE # GPL-2.0+, applies to every theme
└── .editorconfig # shared editor config
Each theme directory is self-contained from WordPress's perspective:
obel/
├── theme.json # THE design system — every token, every block override
├── style.css # WP's required header file (no actual CSS)
├── functions.php # tiny WP filter set (sale-flash, view-transition names, etc.)
├── templates/ # full-site-editing templates (~25 files)
├── parts/ # template parts (header, footer, mini-cart drawer, etc.)
├── patterns/ # block patterns the editor exposes
├── styles/ # style variations (alternate token sets)
├── assets/ # SVGs, fonts, screenshots — never JS, never CSS
├── playground/ # blueprint.json, content.xml, image fixtures
├── screenshot.png # WP appearance screen thumbnail
├── AGENTS.md # per-theme agent rules
├── INDEX.md # generated token + template + style-variation map
├── CHANGELOG.md # human-readable per-theme history
└── SYSTEM-PROMPT.md # short LLM system prompt for one-shot edits
The theme.json is the load-bearing file in every theme. Everything visual flows from it. There are zero .css files in any theme directory (the style.css is a one-line metadata header WP requires).
| Script | Role |
|---|---|
check.py |
The single pre-commit gate. Runs every static check + (optional) snap-gated visual sweep. |
snap.py |
Visual-snapshot framework. Boots WordPress Playground, drives Playwright, captures screenshots + diagnostics, diffs against committed baselines. See Visual Snapshots. |
snap_config.py |
Routes, viewports, inspector selectors, interactions, budgets, noise filters. The single config file for snap.py. |
clone.py |
Scaffolds a new sibling theme from Obel with the names rewritten. |
build-index.py |
Regenerates a theme's INDEX.md (token map, template list, block style list). |
build-redirects.py |
Regenerates docs/<theme>/<page>/index.html short URLs that GH Pages serves. |
validate-theme-json.py |
Validates a theme's theme.json block names against live Gutenberg + WC sources. |
list-templates.py |
Prints every template the theme could ship and the URL it serves. |
list-tokens.py |
Inspects design tokens defined in theme.json. |
seed-playground-content.py |
Populates <theme>/playground/{content,images}/ from the canonical W&O source. |
sync-playground.py |
Inlines playground/*.php into every theme's playground/blueprint.json. |
append-wc-overrides.py |
Generates and appends WooCommerce override CSS chunks into each theme's styles.css. |
Every script accepts a positional theme name, defaults to the cwd if it contains a theme.json, and most support --all to operate on every theme. See Tooling for the full reference.
The repo intentionally keeps generated artifacts close to their source so the diffs make sense to reviewers:
-
<theme>/INDEX.md— committed; regenerated bybin/build-index.py. -
<theme>/playground/blueprint.json— committed; the embedded PHP/SQL is regenerated bybin/sync-playground.py. -
docs/<theme>/<page>/index.html— committed; regenerated bybin/build-redirects.py. -
tests/visual-baseline/<theme>/<viewport>/<route>.png— committed; regenerated when a visual change is intentional viabin/snap.py baseline. -
tmp/snaps/**— gitignored; latest snap output, findings JSON, axe reports. -
tmp/diffs/**— gitignored; per-pixel diff overlays vs the committed baselines. -
bin/vendor/axe.min.js— gitignored; auto-downloaded from a version-pinned CDN URL on first snap run.
Fifty on GitHub · Live demos · GPL-2.0-or-later · Block-only WooCommerce themes, zero CSS files, zero JS, zero build step