EN /HU | Login

Wiki Site

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.

Overview

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.

Content

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:

  • In git — edit default.md, commit, push. The webhook flow below deploys it.
  • In the admin panel (/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/….

Languages

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.

Update flow

  1. Someone pushes to wiki-pages on Gitea, or edits a page in the admin panel.
  2. A Gitea webhook calls the fetcher's /pull. It commits local admin edits first, then git pull --rebase + push.
  3. The repo is bind-mounted, so the pulled changes are live at once.
  4. /api/updates.json lists every page by modification time.
  5. The Updater bot polls it, compares against its cache, and posts a Discord notification per new update.

JSON API

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.

Repository

https://git.teletypegames.org/services/wiki-pages