mirror of
https://github.com/HananoshikaYomaru/openfreebooks.git
synced 2026-11-12 20:45:52 +00:00
5.5 KiB
5.5 KiB
Curriculum & catalog data
data/catalog.json
Site-wide catalog chrome.
{
"title": "Curriculum Catalog",
"subtitle": "Browse chapters by subject and curriculum",
"curriculums": ["Foundation", "DSE", "IB", "A-Level", "AP", "IGCSE", "Common Core"],
"subjects": [
{ "id": "math", "name": "Mathematics" }
]
}
| Field | Rules |
|---|---|
id |
kebab-case, URL-safe; becomes ?subject= and path prefix /{id}/ |
name |
Display label in sidebar |
curriculums |
Union of all filter chips; add new labels here first |
data/{subject}-curriculum.json
Example: data/math-curriculum.json.
{
"title": "Mathematics",
"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": [
{ "from": "quadratic-equations", "to": "sequences-series" },
{ "from": "quadratic-equations", "to": "functions-graphs" },
{ "from": "functions-graphs", "to": "linear-programming" }
]
},
"strands": [
{
"id": "number-algebra",
"title": "Number & Algebra",
"chapters": [
{
"slug": "quadratic-equations",
"title": "Quadratic equations",
"description": "One or two sentences shown in list and map views.",
"status": "live",
"curriculums": ["DSE", "IB"]
}
]
}
]
}
Chapter fields
| Field | Required | Notes |
|---|---|---|
slug |
yes | Matches content/{subject}/{slug}/; kebab-case |
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) |
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)
| Rule | Detail |
|---|---|
| Scope | DSE compulsory topic units (~25–35 chapters); primary/junior not in JSON yet |
| Edges | Required prerequisites only; graph.edges is the sole source (no auto chain from strand array order) |
Scope of from/to |
Any chapter slug — cross-strand edges allowed (arrows may cross columns) |
| Levels | Longest-path from roots: level = 1 + max(level(parent)); roots at 0 |
| List order | strands[].chapters[] array order is for the list tab only (authoring / ToC) |
| Roots | Multiple level-0 chapters per strand OK; edgeless placeholders OK while drafting |
Graph edges
from/toare chapter slugs (not node ids).- Edges must form a DAG (no cycles). Map builder throws on cycles.
- One prerequisite → add one edge. Multiple parents → multiple edges into the same
to. - Branches: one
from→ manyto(e.g. quadratics → sequences and functions-graphs). - Merges: many
from→ oneto(e.g. functions + sequences → linear programming).
Wiring into catalog
themes/openfreebooks/templates/catalog.html must expose strands + graph in #catalog-data. Today only math is wired — adding a subject requires a Tera block like:
{% set subject_catalog = load_data(path="data/science-curriculum.json", format="json") %}
...
"strands": {% if subject.id == "science" %}{{ subject_catalog.strands | json_encode() | safe }}{% else %}[]{% endif %}
Goal (tracked in README): auto-load data/{id}-curriculum.json by subject id.
Status: planned vs live
| status | Catalog list | Map node | Content required |
|---|---|---|---|
planned |
Shown, “Coming soon” badge | Card shown; title not linked | Only JSON entry |
live |
Full card links to chapter | Title links to chapter (→ + underline); rest of card not clickable |
content/ + HTML partial + template wiring |
Map nodes are type: "text" in JSON Canvas; the viewer renders custom HTML via catalog-chapter-card.tsx (renderCatalogChapterCardElement), not markdown.
Adding a curriculum label
- Add string to
data/catalog.json→curriculums. - Tag chapters with that string in
curriculumsarrays. - Add
.catalog-badge--{name}in_catalog.scss(see existing--dse,--ib, …). - Optional:
curriculumBadgeClass()infrontend/src/lib/catalog-badge.ts(defaults exist).
Map card heights (agents)
Do not use fixed node heights or font-metrics libraries for layout. The pipeline is:
measureAllMapChapterCardHeights()— render each card off-screen; readscrollHeight.subjectToCanvas()— assign nodeheightand column Y from DAG levels.- After
json-canvas-viewerpaints,measureRenderedMapChapterCards()+relayoutCanvasChapterHeights()— bump any node still too short and reflow Y / strand groups.
Card markup must stay in sync between catalog-chapter-card.tsx (Solid + renderCatalogChapterCardElement) and _catalog.scss (especially .catalog-chapter-card--map).
Validation (manual until scripted)
- JSON parses (
jq . data/math-curriculum.json). - Every
liveslug hascontent/{subject}/{slug}/_index.md. - Every
curriculums[]value is listed incatalog.json. - Graph edges reference existing slugs; no cycles (open catalog map view).
bun run buildsucceeds.