From d17704d74918b5dc0ff2320ce369fe6ad94c2d58 Mon Sep 17 00:00:00 2001 From: Nozzit <150452728+Nozzit@users.noreply.github.com> Date: Mon, 27 Jul 2026 09:45:05 +0200 Subject: [PATCH] docs: voeg CLAUDE.md toe met repo-conventies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Beschrijft de dingen die niet uit één bestand af te leiden zijn: de twee naamruimtes per tool (paginaslug versus GitHub-repo), de twee losse i18n-motoren, welke bestanden gegenereerd zijn en dus niet met de hand bewerkt mogen worden, de checkerscripts als enige tests, de designtokens, en de checklist voor het toevoegen van een tool. Inclusief de nieuwe canonical- en Open Graph-conventies. Co-Authored-By: Claude --- CLAUDE.md | 104 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 CLAUDE.md diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..5bdb0ec --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,104 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this is + +The OpenAEC Foundation website (https://open-aec.com) — ~47 pages of hand-written static HTML/CSS/JS. **No build step, no `package.json`, no framework, no bundler.** Node is used only for a set of generator scripts under `scripts/`. Deploy is rsync to `/var/www/open-aec.com` on push to `main` (`.github/workflows/deploy.yml`). Everything generated is committed — `.gitignore` contains only `.worktrees/`. + +`README.md` is badly stale (says 16 repos, NL/EN only, GitHub Pages). Do not trust it as a spec. + +## Commands + +Serve locally (the `.claude/launch.json` entry is named `website`, `npx serve` on port 4500): + +```bash +npx serve +``` + +Refresh all GitHub-derived data (stats, news, downloads, homepage chips, api, md mirrors) and commit: + +```bash +node scripts/update-website.js +``` + +Add `--no-commit` to skip the commit. Requires `GITHUB_TOKEN` in the environment (60 vs 5000 req/h). The 7 steps and their read/write dependencies are documented in `.claude/skills/update-website/SKILL.md` — run them individually only in that order. + +### Tests + +There is no test runner. The two checker scripts are the only tests and are **not wired into CI** — run them by hand after touching the homepage, a product page, or the generators: + +```bash +node scripts/check-open-pile-plan-studio.js && node scripts/check-homepage-catalog-product-pages.js +``` + +They use `node:assert/strict` and fail with a Dutch message. `check-open-pile-plan-studio.js` doubles as the executable checklist for adding a new tool (see below). `check-homepage-catalog-product-pages.js` pins several literal CSS colour values in `bim-validator/index.html` and the exact screenshot order in Open Speech Studio — those assertions are deliberate, not accidental. + +## Architecture + +### Two name spaces per tool + +Every tool has a **page slug** and a **GitHub repo name**, and they usually differ (`open-pile-plan-studio` vs `pile-plan-studio`). Slug is used for the directory, `meta[name=i18n-page]`, `shared/translations/*`, `md/*.md`, and the `id` in `api/tools.json`. Repo name is used for `data-repo`, `data-release-notes`, `data/release-notes/*.json`, and the repo lists inside the generator scripts. `build-homepage-stats.js` lowercases repo names when matching; everything else preserves casing. + +### i18n — two separate engines + +Four languages: **nl (default, the literal HTML text), en, fr, tr**. Preference in `localStorage` under `openaec-lang`. Language is client-side only — there are no per-language URLs and no `hreflang` anywhere. + +- **Subpages** use `shared/i18n.js`. A page declares ``; translations load from `/shared/translations/.json` (EN) and `.fr.json` / `.tr.json` (with EN fallback). Nodes carry `data-i18n="dotted.key"`, attributes use `data-i18n-attr`. NL originals are cached into `data-i18n-nl` on first switch. Without the meta tag only inline-attribute translation runs. +- **The homepage does not use it.** `index.html` has a self-contained inline `const translations = { nl, en, fr, tr }` (~line 1686) plus its own `detectLang()`/`i18n` object. Adding a tool means adding `tools.items.` to **all four** objects — the pile-plan checker asserts exactly 4 occurrences of the key. +- Nav links use inline `data-i18n-en` / `-fr` / `-tr` attributes in `shared/nav.html`, not JSON. + +`shared/nav.js` fetches and injects `shared/nav.html` into `#shared-nav` (auto-creating the placeholder if absent), then dispatches a `nav:loaded` CustomEvent; `shared/i18n.js` listens for it to translate the late-injected nav. There is no MutationObserver — deliberately. + +### Product page skeleton + +`/index.html`, ``, head order: charset → viewport → title → description → `meta name="i18n-page"` → favicon → `/shared/style.css` → inline `SoftwareApplication` JSON-LD → page-local `