7.8 KiB
Contributing to Open Free Books
Thank you for helping grow free, open textbooks. This guide focuses on curriculum, subjects, and chapters — the most common contribution.
Prerequisites: Zola, Bun. See README.md for dev setup.
Quick reference
| I want to… | Start here |
|---|---|
| Add a planned chapter (roadmap only) | § Planned chapter |
| Publish a live chapter (readable page) | § Live chapter |
| Add a branch in the catalog map | § Chapter graph |
| Add a new subject | § New subject |
| Add a curriculum filter (e.g. GCSE) | § New curriculum label |
Browse the catalog locally: bun run build:js && zola serve → http://127.0.0.1:1111/catalog/
How the catalog fits together
data/catalog.json → subjects in the sidebar + filter chips (DSE, IB, …)
data/{subject}-curriculum.json → strands, chapters, curriculum tags, optional graph
content/{subject}/{slug}/ → actual chapter page (when status is "live")
themes/.../partials/... → chapter HTML content (today)
- Catalog (
/catalog/) is the place to browse everything.- List — numbered chapter cards; live chapters link to the whole card.
- Map — strand columns on a pannable JSON Canvas graph; live chapters link from the title only (with
→and a hover underline).
/math/redirects to/catalog/?subject=math— there is no separate math book homepage.- Curriculum names (DSE, IB, …) appear only in the catalog — not inside chapter text (spec.md).
- Every chapter needs a short
descriptionin curriculum JSON (shown in list and map; map clamps description to three lines).
Add a planned chapter (roadmap)
Use this when the chapter is not written yet but should appear in the catalog.
- Open
data/{subject}-curriculum.json(e.g.data/math-curriculum.json). - Find the right strand (topic group).
- Add a chapter object:
{
"slug": "your-chapter-slug",
"title": "Human-readable title",
"description": "One or two sentences for the catalog list and map card.",
"status": "planned",
"curriculums": ["DSE"]
}
- Use a kebab-case
slug(letters, numbers, hyphens only). - Set
curriculumsto every syllabus tag that applies. Tags must exist indata/catalog.json→curriculums. - Run
zola buildand check/catalog/?subject=math(or your subject).
No content/ files needed for planned chapters.
Publish a live chapter
A live chapter needs catalog data and a page.
1. Catalog entry
In data/{subject}-curriculum.json, set "status": "live" and include a description for the chapter (see planned chapter).
2. Zola section
Create content/{subject}/{slug}/_index.md:
+++
title = "Your chapter title"
description = "One sentence for search and previews — no curriculum names here."
template = "math/chapter.html"
weight = 10
[extra]
chapter_id = "your-chapter-slug"
+++
slugin the path must matchslugin the JSON file.chapter_idmust match the slug (used by the template).weightcontrols order within the section (lower = earlier).
3. Chapter HTML content
Today, chapter bodies live as HTML partials under the theme, not Markdown:
- Add
themes/openfreebooks/templates/partials/math/your-chapter-slug-content.htmlwith the lesson HTML. - In
themes/openfreebooks/templates/math/chapter.html, include it whenchapter_idmatches:
{% if section.extra.chapter_id == "your-chapter-slug" %}
{% include "partials/math/your-chapter-slug-content.html" %}
{% endif %}
Use existing classes: book-prose, book-prose__heading, book-callout, etc. Copy from quadratic-equations-content.html.
Do not mention DSE, IB, or other curriculum names in the chapter body.
4. Interactive widgets (optional)
If the chapter needs a Solid widget (like the quadratic explorer):
- Add a component under
frontend/src/components/. - Mount it in
frontend/src/main.tsxwhen a mount element exists. - Add
<div id="your-widget" class="math-widget-mount"></div>in the chapter template branch.
Then run bun run build:js.
5. Check
/catalog/?subject=math— chapter appears; live chapters link correctly./math/your-chapter-slug/— page renders; breadcrumb goes to catalog.bun run buildcompletes without errors.
Chapter graph (branches)
The Map tab (?view=tree) shows chapters as a directed graph on a canvas (strand = column, arrows = prerequisites / sequence).
- Chapters appear as cards with title, description, and curriculum badges.
- Live chapters: click the title to open the chapter (not the whole card).
- Planned chapters: shown with a “Coming soon” badge; no link.
- By default, chapters in a strand link in list order (chapter 1 → chapter 2 → …).
- For branches (one chapter leads to several next chapters), add
graph.edges:
"graph": {
"edges": [
{ "from": "quadratic-equations", "to": "sequences" },
{ "from": "quadratic-equations", "to": "functions-graphs" }
]
}
Rules:
fromandtoare chapter slugs.- The graph must not contain cycles (no circular prerequisites).
- Edges must reference slugs that exist in
strands.
Open /catalog/?subject=math&view=tree to verify layout. Scroll the page normally; use Ctrl/Cmd + wheel on the map to zoom. Pan by clicking the map first if the “click to interact” banner appears.
If a map card looks clipped at the bottom (badges or description cut off), that is a layout bug — long titles and descriptions need enough node height. Report it or see curriculum-data.md for how heights are measured.
Add a new subject
Example: adding Science.
-
data/catalog.json— add tosubjects:{ "id": "science", "name": "Science" } -
data/science-curriculum.json— create withtitle,strands, and chapters (copy structure frommath-curriculum.json). -
themes/openfreebooks/templates/catalog.html— today you must wire the new file into#catalog-data(seemathblock). This step should get easier; see README contributor tasks. -
content/science/— add_index.md(redirect template like math) when you have a section. -
Homepage — optional card in
themes/openfreebooks/templates/index.html. -
Build and test
/catalog/?subject=science.
Add a curriculum label
Example: adding GCSE.
- Add
"GCSE"tocurriculumsindata/catalog.json. - Tag chapters with
"GCSE"in theircurriculumsarrays. - Add a badge style in
themes/openfreebooks/sass/_catalog.scss(copy.catalog-badge--igcsepattern). - Add a mapping in
frontend/src/lib/catalog-badge.ts→curriculumBadgeClass()(or rely on the default style).
Pull requests
- Keep changes focused (one subject or a few chapters per PR is fine).
- Run
bun run buildbefore opening the PR. - Do not commit
public/or copied HTML underthemes/openfreebooks/static/. - Do commit Vite output under
themes/openfreebooks/static/js/(bundle.jsand hashed chunks such ascatalog-app-*.js,catalog-canvas-view-*.js) afterbun run build:js. - Describe what you added in the PR: subject, chapters, live vs planned, and which curricula apply.
Questions? Open a GitHub discussion or issue.
For maintainers & agents
Machine-oriented detail: .agents/skills/ofb/SKILL.md and .agents/skills/ofb/curriculum-data.md.