tane/TRANSLATIONS.md
vjrj 2d4dec5304 docs(i18n): correct site Weblate format to go-i18n-json-v2
The object-form go-i18n JSON ({"key":{"other":...}}) is parsed by Weblate's
go-i18n-json-v2 format, not go-i18n-json (which expects a top-level array).
2026-07-15 19:46:16 +02:00

4.4 KiB

Translating Tane (Weblate)

Runbook for the translation setup. Written so another agent (or a human) can reproduce it without prior context.

Tane is translated on translate.comunes.org/projects/tane (a self-hosted Weblate 5.x, docker-compose at /data/weblate on host tesla). The links to the repo and to Weblate are shown both on the landing site (site/config.tomlsourceURL, weblateURL) and inside the app (About screen).

What is translatable

Surface Files Format Base locale Locales today
App (app component) apps/app_seeds/lib/i18n/*.i18n.json JSON nested (slang, {param} placeholders) en en, es, pt, fr, de, ast, ja
Site (site component) site/i18n/*.json go-i18n JSON ({"key":{"other":"…"}}) en en, es

Only source strings live in git; app strings use slang, so strings.g.dart / strings_*.g.dart are generated (see the slang caveat below).

Git connection

  • Repo: https://git.comunes.org/comunes/tane.git, branch main (private Gitea/Forgejo behind Cloudflare).
  • Weblate must use HTTPS + an access token — SSH port 22 is not reachable through Cloudflare, so the stored Comunes Translations SSH key is unusable here.
  • Repository URL in Weblate: https://<user>:<token>@git.comunes.org/comunes/tane.git where <token> is a git.comunes.org access token with read + write on comunes/tane (Weblate pushes translations back). Generate it in Gitea/Forgejo → Settings → Applications.

The app component (create once)

The tane project already exists on Weblate. Add a component (admin UI Add new translation component, or docker exec weblate-weblate-1 weblate shell):

Field Value
Project tane
Name / slug app
Source code repository https://<user>:<token>@git.comunes.org/comunes/tane.git
Repository branch main
File mask apps/app_seeds/lib/i18n/*.i18n.json
Monolingual base language file apps/app_seeds/lib/i18n/en.i18n.json
Template for new translations apps/app_seeds/lib/i18n/en.i18n.json
File format JSON nested structure (json-nested) — not flat json
Source language English (en)

Weblate auto-discovers the existing locales from the mask. Leave push-on-commit on so translations flow back to main.

Sanity check after creating it:

docker exec weblate-weblate-1 weblate shell -c \
  'from weblate.trans.models import Project; \
   print(Project.objects.get(slug="tane").component_set.count())'   # expect 1

Then edit a test string in the UI and confirm a commit lands on git.comunes.org/comunes/tane (main) — that validates the token has write.

slang regeneration caveat (important)

Weblate only edits the *.i18n.json sources. The committed strings.g.dart / strings_*.g.dart are generated and go stale on every Weblate commit, and there is no CI to regenerate them. Before a release, a maintainer must:

git pull
cd apps/app_seeds && dart run slang     # regenerates strings*.g.dart
cd ../.. && dart analyze                 # workspace gate
git add -A && git commit -m "chore(i18n): regenerate slang after Weblate sync"

(Adding a new source string manually? Same steps — edit en.i18n.json first, then regenerate. fallback_strategy: base_locale means locales missing a key show the English text until translators fill it in.)

The site component (landing page)

The Hugo landing strings live in site/i18n/*.json. Weblate has no native Hugo-TOML format, so these were converted from TOML to go-i18n JSON ({"key":{"other":"…"}}) — a shape Hugo 0.140 reads identically and Weblate supports natively. Component settings:

Field Value
Project tane
Name / slug site
Source code repository (link to the app component: weblate://tane/app)
Repository branch main
File mask site/i18n/*.json
Monolingual base language file site/i18n/en.json
Template for new translations site/i18n/en.json
File format go-i18n v2 JSON (go-i18n-json-v2)
Source language English (en)

Linking the repo to the app component (weblate://tane/app) shares one clone/token. No slang step here — Hugo consumes the JSON directly. Only EN/ES today; adding a locale = add site/i18n/<code>.json.