This wiki is a Grav CMS site whose content lives in a git repository, plus two companion services: a fetcher that syncs the repo on git webhooks, and a telnet BBS front-end. Changes surface on a JSON API, which the Updater bot polls to announce them on Discord.
One repository holds everything — services/wiki-pages: content (pages/), Grav config, theme, companion services. Docker Compose runs three services from it:
| Service | What it does |
|---|---|
grav |
Grav CMS (PHP 8.1 + Apache). pages/, config/, themes/ are bind-mounted, so the site serves the working tree. |
wiki-fetcher |
Go HTTP hook (fetcher/). GET /pull?secret=… commits local edits, rebase-pulls, pushes. |
wiki-bbs |
Telnet front-end (bbs/, on rubbs) browsing the wiki through the JSON API. See BBS Server. |
Grav routes by folder: a page is pages/<section>/<slug>/default.md with YAML frontmatter. The sidebar is curated by hand in config/sitenav.yaml. Two ways to edit:
default.md, commit, push. The webhook flow below deploys it./admin) — Grav writes into the bind-mounted working tree, and the fetcher commits it back to git on its next /pull.Pages under projects/ and team/ need a login. Images live in assets/, served at /wiki-assets/….
The wiki is bilingual: English is the default and has no URL prefix, Hungarian lives under /hu. A page carries its language in its filename — default.en.md or default.hu.md — and the language switcher sits in the top bar.
English pages have a Hungarian translation. Hungarian-only pages (the association paperwork, the meeting notes, the Neumatronic Universe lore) do not get an English one: content_fallback in config/system.yaml makes the English request fall through to the Hungarian file, so nothing 404s.
The JSON API follows the same rule: /custom/pages.json is English, /hu/custom/pages.json is Hungarian. Each response echoes the requested lang, and every page carries a locale saying which language its body is actually written in — the two differ exactly where the fallback kicked in.
wiki-pages on Gitea, or edits a page in the admin panel./pull. It commits local admin edits first, then git pull --rebase + push./api/updates.json lists every page by modification time.The endpoints are Grav pages (pages/api/) rendered by twig templates in themes/ttgwiki/templates/:
| Endpoint | Purpose |
|---|---|
/api/sitemap.json |
Every routable page: route, title, modified, tags, private flag (no bodies). |
/api/page.json?route=<route> |
One page with raw markdown + rendered HTML. |
/api/updates.json?limit=N |
Pages ordered by modification time — this is what the Updater bot watches. |
/api/pages.json?tag=<tag> |
Pages filtered by taxonomy tag (the public site's Blog and HowTos feeds use this). |
A private page exposes its body only with token=<SUPERVISOR_PASSWORD>. The BBS uses the same token for its supervisor login.
https://git.teletypegames.org/services/wiki-pages