mirror of
https://github.com/HananoshikaYomaru/openfreebooks.git
synced 2026-11-13 21:15:54 +00:00
Enhance curriculum catalog functionality: Update CONTRIBUTING.md to reflect changes in curriculum structure, including the introduction of curriculumCoverage for frameworks. Modify frontend components to support a new comparison view for Mathematics, allowing users to compare curricula. Update catalog data to include "Common Core" and improve curriculum filtering logic. Enhance styles for better visual representation of curriculum badges and Mermaid diagrams. Adjust TypeScript types to accommodate new features and ensure backward compatibility with legacy curriculum data.
This commit is contained in:
parent
ede9a7aa63
commit
5175811579
34 changed files with 3702 additions and 176 deletions
|
|
@ -93,7 +93,7 @@ Detailed checklists: [curriculum-data.md](curriculum-data.md). Human-facing guid
|
|||
| Styles | `themes/openfreebooks/sass/_catalog.scss` |
|
||||
|
||||
- Embedded data: `#catalog-data` in `templates/catalog.html` (merged at build time)
|
||||
- URL: `/catalog/?subject=math` (list), `&view=tree` (map)
|
||||
- URL: `/catalog/?subject=math` (list), `&view=tree` (map), `&view=compare` (math curricula doc — HTML partial `partials/math-curricula-compare.html`)
|
||||
|
||||
**List view:** full-card link for live chapters; number + title row on wide screens.
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ Site-wide catalog chrome.
|
|||
{
|
||||
"title": "Curriculum Catalog",
|
||||
"subtitle": "Browse chapters by subject and curriculum",
|
||||
"curriculums": ["DSE", "IB", "A-Level", "AP", "IGCSE"],
|
||||
"curriculums": ["Foundation", "DSE", "IB", "A-Level", "AP", "IGCSE", "Common Core"],
|
||||
"subjects": [
|
||||
{ "id": "math", "name": "Mathematics" }
|
||||
]
|
||||
|
|
@ -28,7 +28,8 @@ Example: `data/math-curriculum.json`.
|
|||
```json
|
||||
{
|
||||
"title": "Mathematics",
|
||||
"subtitle": "Short tagline for data (not shown on every page)",
|
||||
"subtitle": "Optional; deprecated — do not use HKDSE-only framing. Catalog chrome uses data/catalog.json.",
|
||||
"intro": "Optional subject-level intro (not shown in catalog UI today)",
|
||||
"intro": "Optional; was used by old book page",
|
||||
"graph": {
|
||||
"edges": [
|
||||
|
|
@ -63,8 +64,9 @@ Example: `data/math-curriculum.json`.
|
|||
| `title` | yes | Catalog list + map node label |
|
||||
| `description` | yes | 1–2 sentences; shown in list and map cards (clamped to 3 lines on map) |
|
||||
| `status` | yes | `live` (link to chapter) or `planned` (no link) |
|
||||
| `curriculums` | yes | Non-empty array; values must exist in `catalog.json` `curriculums` |
|
||||
| `tier` | no | `foundation` (default) or `non-foundation` — shows an **Extension** badge on cards |
|
||||
| `curriculumCoverage` | yes (math) | Object mapping framework label → `core` \| `extension` \| `related` (Compare matrix + filters) |
|
||||
| `curriculums` | legacy | Deprecated array; use `curriculumCoverage` instead |
|
||||
| `tier` | no | `foundation` (default) or `non-foundation` — shows an **Extension** badge on cards (DSE M2-style topics) |
|
||||
|
||||
### Graph model (map)
|
||||
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ Static site: **Zola** + custom theme `openfreebooks`. Output goes to `public/` (
|
|||
| `static/` | Copied to site root (`favicons`, `icons/`, etc.) |
|
||||
| `themes/openfreebooks/templates/` | Tera HTML, partials, macros |
|
||||
| `themes/openfreebooks/sass/` | Source styles → compiled `public/main.css` |
|
||||
| `themes/openfreebooks/static/js/` | Vite output: `bundle.js` (site chrome) + hashed chunks (`catalog-app-*.js`, `catalog-canvas-view-*.js`, …) |
|
||||
| `themes/openfreebooks/static/js/` | Vite output: `bundle.js` (site chrome) + lazy chunks (e.g. `catalog-mermaid-view-*.js`) |
|
||||
|
||||
See [reference.md](reference.md) for Tera pitfalls and build checks.
|
||||
|
||||
|
|
@ -75,10 +75,12 @@ Client behavior lives in `frontend/` and mounts from `base.html`:
|
|||
| Entry | Mount | Notes |
|
||||
|-------|--------|--------|
|
||||
| `js/bundle.js` | `main.tsx` | Header, theme, homepage, chapter widgets |
|
||||
| `js/catalog-app-*.js` | `#catalog-app` on `/catalog/` | Lazy-loaded with `catalog-canvas-view-*.js` for Map view |
|
||||
| `#catalog-app` on `/catalog/` | `catalog-app.tsx` in bundle | List / Map / Compare; Map lazy-loads `catalog-mermaid-view` |
|
||||
|
||||
**When changing `frontend/` or adding interactivity**, read [zola-solid.md](zola-solid.md) before editing JS.
|
||||
|
||||
**When changing the catalog page, map, or compare doc**, read [zola-catalog.md](zola-catalog.md).
|
||||
|
||||
### Search (Pagefind)
|
||||
|
||||
- Runs after `zola build`; indexes **live chapter pages** only (`data-pagefind-body` on chapter template).
|
||||
|
|
@ -87,8 +89,10 @@ Client behavior lives in `frontend/` and mounts from `base.html`:
|
|||
### Catalog page
|
||||
|
||||
- `content/catalog.md` → `template = "catalog.html"`
|
||||
- `templates/catalog.html` — empty `#catalog-app` + `#catalog-data` JSON embed (merged subject curricula at build time)
|
||||
- `sass/_catalog.scss` — list + map styles; map card title link underline lives under `.catalog-canvas`
|
||||
- `templates/catalog.html` — `#catalog-app`, `#catalog-data` JSON, `<template id="catalog-compare-template">` (math compare partial)
|
||||
- Views: list (default), `?view=tree` (Mermaid DAG map), `?view=compare` (math curricula doc)
|
||||
- Map colors: Mermaid `theme: "base"` + hex `themeVariables` in `frontend/src/lib/catalog-mermaid-theme.ts` — **not** Sass `fill` on cluster rects (inline SVG wins)
|
||||
- Full file map, strand header post-render, and verify steps: [zola-catalog.md](zola-catalog.md)
|
||||
- Run `bun run build:js` after any `frontend/src/components/catalog-*` or `frontend/src/lib/catalog-*` change
|
||||
|
||||
## Verify
|
||||
|
|
|
|||
|
|
@ -46,6 +46,16 @@ If styles “don’t apply”, delete stray `themes/openfreebooks/static/main.cs
|
|||
- `static/contributors.json` — optional mirror for `/contributors.json` if needed.
|
||||
- Contributors UI: `partials/contributors-block.html`; credits page: `credits.html` + `partials/credits-content.html`.
|
||||
|
||||
## Catalog URLs
|
||||
|
||||
| URL | View |
|
||||
|-----|------|
|
||||
| `/catalog/?subject=math` | List |
|
||||
| `/catalog/?subject=math&view=tree` | Mermaid map |
|
||||
| `/catalog/?subject=math&view=compare` | Math curricula compare (HTML partial) |
|
||||
|
||||
Catalog build/data/Mermaid details: [zola-catalog.md](zola-catalog.md).
|
||||
|
||||
## Social icons
|
||||
|
||||
1. Source SVGs: `static/icons/social/{kind}.svg` (from [Tabler Icons](https://tabler.io/icons) outline set).
|
||||
|
|
|
|||
96
.agents/skills/zola/zola-catalog.md
Normal file
96
.agents/skills/zola/zola-catalog.md
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
# Catalog page (Zola + Solid + Mermaid)
|
||||
|
||||
Read this when editing `/catalog/`, `templates/catalog.html`, `sass/_catalog.scss`, or `frontend/src/**/catalog-*`.
|
||||
|
||||
## Zola side
|
||||
|
||||
| Piece | Path |
|
||||
|-------|------|
|
||||
| Page | `content/catalog.md` → `template = "catalog.html"` |
|
||||
| Shell | `themes/openfreebooks/templates/catalog.html` |
|
||||
| Compare doc (math only) | `templates/partials/math-curricula-compare.html` — embedded in `<template id="catalog-compare-template">` |
|
||||
| Build-time JSON | `#catalog-data` — merged subject curricula from `data/{subject}-curriculum.json` + `data/catalog.json` |
|
||||
| Styles | `themes/openfreebooks/sass/_catalog.scss` |
|
||||
|
||||
**Tera:** never bind curriculum JSON to a variable named `math` (reserved). Use `math_catalog`, etc.
|
||||
|
||||
## URL and views
|
||||
|
||||
| View | `view` param | UI |
|
||||
|------|----------------|-----|
|
||||
| List (default) | (omit) | Strand sections + `CatalogChapterCard` |
|
||||
| Map | `tree` | Lazy `CatalogMermaidView` — DAG from `graph.edges` |
|
||||
| Compare | `compare` | Math only — `CatalogCompareDoc` clones compare partial HTML |
|
||||
|
||||
Example: `/catalog/?subject=math&view=tree`
|
||||
|
||||
Curriculum filter chips come from `data/catalog.json` → `curriculums[]`. Math chapters use `curriculumCoverage` in `math-curriculum.json` (`core` / `extension` / `related` per framework). Compare matrix uses all roles; list/map badges show framework labels only.
|
||||
|
||||
## Solid / Vite
|
||||
|
||||
| Piece | Path |
|
||||
|-------|------|
|
||||
| App shell | `frontend/src/components/catalog-app.tsx` |
|
||||
| List card | `frontend/src/components/catalog-chapter-card.tsx` |
|
||||
| Compare mount | `frontend/src/components/catalog-compare-doc.tsx` |
|
||||
| Map viewer | `frontend/src/components/catalog-mermaid-view.tsx` (lazy chunk `catalog-mermaid-view-*.js`) |
|
||||
| Mermaid source | `frontend/src/lib/catalog-to-mermaid.ts` |
|
||||
| Theme (hex) | `frontend/src/lib/catalog-mermaid-theme.ts` |
|
||||
| Strand header chrome | `frontend/src/lib/catalog-mermaid-strand-headers.ts` |
|
||||
| Light/dark mode | `frontend/src/lib/catalog-canvas-theme.ts` (`siteCanvasTheme`, `watchSiteTheme`) |
|
||||
| Badge classes | `frontend/src/lib/catalog-badge.ts` |
|
||||
| Types | `data/catalog.types.ts` (`CatalogViewMode`: `"linear" \| "tree" \| "compare"`) |
|
||||
|
||||
After any catalog frontend change: `bun run build:js` then hard-refresh.
|
||||
|
||||
## Mermaid map — theming (important)
|
||||
|
||||
Mermaid writes **inline `fill` on SVG nodes**. CSS `fill` on `.cluster rect` does **not** override themed colors.
|
||||
|
||||
| Rule | Detail |
|
||||
|------|--------|
|
||||
| Custom colors | Only with `theme: "base"` + `themeVariables` (hex). Other themes (`default`, `dark`, …) are not customizable via variables. |
|
||||
| Color format | Hex only (`#121110`). Named colors (`red`) are ignored by the theming engine. |
|
||||
| Site-wide init | `mermaid.initialize({ …mermaidInitializeOptions(mode) })` in `catalog-mermaid-view.tsx` |
|
||||
| Strand subgraph body | `clusterBkg` in `mermaidThemeVariables()` |
|
||||
| Strand title band | `secondaryColor` — also applied to overlay header rect in `enhanceStrandClusterHeaders()` |
|
||||
| Borders / edges | `clusterBorder`, `lineColor`, `nodeBorder`, etc. |
|
||||
|
||||
Do **not** try to drive strand cluster fills from Sass variables on `.cluster rect`; keep SCSS for typography, label chrome, and map chrome (pan/zoom, card links).
|
||||
|
||||
### Strand subgraph titles
|
||||
|
||||
Mermaid puts subgraph titles on the cluster border. Post-render:
|
||||
|
||||
1. `enhanceStrandClusterHeaders(svg, mode)` finds `g.cluster` ids containing `strand_`
|
||||
2. Inserts header `rect` + rule `line` at `STRAND_HEADER_HEIGHT` (44px)
|
||||
3. Repositions `foreignObject` label into the header band
|
||||
4. Sets `rx="0"` on cluster frame (square corners)
|
||||
|
||||
Diagram source uses HTML in subgraph titles, e.g. `<header class='catalog-mermaid-strand__header'>…</header>` — see `catalog-to-mermaid.ts`.
|
||||
|
||||
### Map chapter cards
|
||||
|
||||
List and map share card markup via `CatalogChapterCard`. In the map, only the **title** is a link for live chapters; planned chapters are non-clickable.
|
||||
|
||||
## Sass notes (`_catalog.scss`)
|
||||
|
||||
- Curriculum badge tokens and dark-mode contrast live here.
|
||||
- Map card title underline: under `.catalog-mermaid-view` / `.catalog-canvas` legacy class names if present.
|
||||
- Strand label styling: `.catalog-mermaid-strand__header`, `.catalog-mermaid-strand-label-fo` — not cluster `fill`.
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
bun test frontend/src/lib/catalog-to-mermaid.test.ts
|
||||
bun test frontend/src/lib/catalog-mermaid-theme.test.ts
|
||||
bun test frontend/src/lib/catalog-mermaid-strand-headers.test.ts
|
||||
```
|
||||
|
||||
## Verify locally
|
||||
|
||||
```bash
|
||||
bun run build:js && zola serve
|
||||
```
|
||||
|
||||
Open `/catalog/?subject=math`, toggle List / Map / Compare (math), and switch site light/dark — strand header band should differ from subgraph body in both modes.
|
||||
|
|
@ -48,7 +48,8 @@ Prefer **bootstrap** components that `querySelector` existing markup over re-ren
|
|||
|
||||
- `outDir`: `themes/openfreebooks/static`
|
||||
- `emptyOutDir: false` — do not wipe theme static (only add `js/bundle.js`)
|
||||
- Single entry: `frontend/src/main.tsx` → `js/bundle.js`
|
||||
- Entry: `frontend/src/main.tsx` → `js/bundle.js`
|
||||
- Lazy chunks: e.g. `import("./catalog-mermaid-view")` → `js/catalog-mermaid-view-[hash].js`
|
||||
|
||||
## Workflow
|
||||
|
||||
|
|
@ -57,6 +58,20 @@ Prefer **bootstrap** components that `querySelector` existing markup over re-ren
|
|||
3. Hard-refresh browser.
|
||||
4. For production: `bun run build` then `wrangler deploy`.
|
||||
|
||||
## Catalog (Solid + Mermaid)
|
||||
|
||||
Mounted from `catalog.html` via `catalog-app.tsx` (in main bundle). Map view lazy-loads `catalog-mermaid-view.tsx`.
|
||||
|
||||
| Concern | Module |
|
||||
|---------|--------|
|
||||
| Diagram source | `lib/catalog-to-mermaid.ts` |
|
||||
| Mermaid init / hex theme | `lib/catalog-mermaid-theme.ts` → `mermaidInitializeOptions(mode)` |
|
||||
| Strand title band overlay | `lib/catalog-mermaid-strand-headers.ts` |
|
||||
| Light/dark for map | `lib/catalog-canvas-theme.ts` |
|
||||
| Compare tab HTML | `catalog-compare-doc.tsx` reads `#catalog-compare-template` |
|
||||
|
||||
**Mermaid theming:** use `theme: "base"` and hex `themeVariables` only; CSS cannot override Mermaid’s inline cluster fills. See [zola-catalog.md](zola-catalog.md).
|
||||
|
||||
## KaTeX (math)
|
||||
|
||||
| Use case | API | Where |
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue