# WTHB-TOC-Language-Pipeline

> Wie das Inhaltsverzeichnis des deutschen webtrees-Handbuchs erzeugt wird (GenWiki → pywikibot → Generierung → externes Repo / Pages / Weblate → Modul)

---

## Überblick

Das Paket **`linkenhancer-wthb-toc-lang`** stellt das Inhaltsverzeichnis (TOC) des deutschen webtrees-Handbuchs — samt Übersetzungen — der [WTHB-Hilfefunktion](../features/wthb) zur Verfügung. Die Produktion ist ein **Rundlauf**, der komplett außerhalb der webtrees-Installation läuft: Er liest das Handbuch von **GenWiki**, erzeugt das TOC neu, schreibt das Ergebnis als **MediaWiki-Template** zurück nach GenWiki und — parallel — die strukturierten Daten in ein **externes Codeberg-Repo**, das **Codeberg Pages**, **Weblate** (Übersetzungen) und schließlich das **Modul** versorgt. Diese Seite dokumentiert die *Produktionsseite*; die *Konsumenten-Seite* (Cache, CLI, Rendering) steht auf der [WTHB-Funktionsseite](../features/wthb) und der Seite [CLI-Skripte](cli-scripts).

### Ressourcen
- GenWiki Webtrees Handbuch: <https://wiki.genealogy.net/Webtrees_Handbuch>
- Code-Repositories:
  - Modul: <https://codeberg.org/bschwede/linkenhancer>
  - TOC-Übersetzung: <https://codeberg.org/bschwede/linkenhancer-wthb-toc-lang>
- Weblate-Übersetzungskomponente: <https://translate.codeberg.org/projects/wt-modules/linkenhancer-wthb-toc>
- GenWiki Bot-Projekt: <https://gitlab.genealogy.net/genwiki/wikibots> (gw-skripte / [pywikibot Dokumentation](https://doc.wikimedia.org/pywikibot/stable/introduction.html))

## Pipeline

Der Rundlauf hat zwei Hälften: den **GenWiki-Rundlauf** (Handbuch lesen → generieren → TOC-Template zurück schreiben) und die **Delivery-Pipeline** (strukturierte Daten → externes Repo → Pages / Weblate → Modul).

Der GenWiki-Rundlauf:




<pre class="mermaid">flowchart TB
    subgraph HOST[&#34;🖥️ Host · gw-skripte/&#34;]
        ORCH[&#34;`🚦 **wt-maintain.sh**&lt;br/&gt;*Orchestrierung*`&#34;]
        PREAD[&#34;`🤖 **pywikibot** · *wt-maintain.py*&lt;br/&gt;SectionsExportBot — *READ*`&#34;]
        GEN[&#34;`⚙️ **wt-gen-toc.py** *(pandas)*`&#34;]
        PREP[&#34;`📄 *pagefromfile-Datei*&lt;br/&gt;vorlage_wt-verzeichnis-toc.txt`&#34;]
        PWRITE[&#34;`🤖 **pywikibot** · *pagefromfile*&lt;br/&gt;*WRITE* — Bot-Zusammenfassung`&#34;]
    end

    GW[&#34;`📖 **GenWiki** · wiki.genealogy.net&lt;br/&gt;*Webtrees-Handbuch-Seiten*`&#34;]
    CSV[&#34;`📄 *3 CSV*&lt;br/&gt;pageinfo · sections · images`&#34;]
    OUT[&#34;`📦 *Ausgaben*&lt;br/&gt;wthb-toc.wiki · .html · .json · de.json`&#34;]
    TPL[&#34;`📖 **Vorlage:WT-Verzeichnis-TOC**&lt;br/&gt;*noinclude &#43; includeonly TOC*`&#34;]
    API[&#34;`🔍 *API action=parse* → HTML&lt;br/&gt;(curl &#43; jq)`&#34;]

    GW --&gt;|&#34;allpages prefix &#39;Webtrees Handbuch&#39;&lt;br/&gt;API parse/sections &#43; imagelinks&#34;| PREAD
    ORCH -.-&gt;|&#34;drives&#34;| PREAD
    PREAD --&gt; CSV
    CSV --&gt;|&#34;&#43; wthb-pageinfo_ext.csv (target)&#34;| GEN
    GEN --&gt; OUT
    OUT --&gt; PREP
    PREP --&gt; PWRITE
    PWRITE --&gt;|&#34;pagefromfile -force&#34;| TPL
    TPL --&gt;|&#34;curl API parse&#34;| API

    classDef srcStyle fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
    classDef coreStyle fill:#ede7f6,stroke:#5e35b1,stroke-width:2px
    classDef okStyle fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
    classDef pwbStyle fill:#fff8e1,stroke:#f57f17,stroke-width:2px
    classDef targetStyle fill:#fce4ec,stroke:#ad1457,stroke-width:2px

    class GW srcStyle
    class ORCH,GEN coreStyle
    class CSV,OUT,API okStyle
    class PREAD,PWRITE pwbStyle
    class TPL targetStyle
</pre>

## Orchestrierung — `wt-maintain.sh`

Alles läuft von einem Host-Skript (in `gw-skripte/`):

```bash
wt-maintain.sh <wthb-pageinfo_ext.csv> <DATADIR>
```

Es benötigt `setenv.sh`, das `PWB_PY`, `PWB_CONF` und `SCRIPTDIR` exportiert, und steuert diese Schritte der Reihe nach:

1. GenWiki-Daten abfragen (pywikibot READ)
2. TOC generieren
3. [`pagefromfile`](https://doc.wikimedia.org/pywikibot/stable/scripts_ref/scripts.html#module-scripts.pagefromfile)-Wrapper-Datei bauen
4. Template zurück nach GenWiki schreiben (pywikibot WRITE)
5. gerendertes Template per Parse-Check prüfen (curl + jq)
6. JSON in das externe Repo deployen
7. nachgelagert: Repo-CI, Weblate und Modul holen die Daten

## GenWiki-Datenabfrage (pywikibot READ)

Schritt 1 ist `wt-maintain.py`, ein pywikibot-Bot (`SectionsExportBot`, erbt von `ExistingPageBot`). Er ruft `site.login()` auf, iteriert `allpages(prefix="Webtrees Handbuch")` und fragt pro Seite die [MediaWiki-API](https://www.mediawiki.org/wiki/API:Action_API) (`action=parse&prop=sections`) plus `imagelinks()` (FilePage-Info) ab. \
Ergebnis sind **drei CSV-Dateien**:
1. `wthb-pageinfo.csv`,
2. `wthb-sections.csv` und
3. `wthb-images.csv`.

Zwei manuelle Nacharbeiten bleiben (laut Skript-Header): (b) das Bilderverzeichnis pflegen und (c) die Bilder in die `Kategorie:Webtrees` legen — von Hand (Helfer: `wt-webtrees-cat-files.sh`).

## TOC-Generierung — `wt-gen-toc.py`

Schritt 2 ist ein pandas-Skript, das den **IST**-Zustand (die drei CSVs) mit der **SOLL**-Zielstruktur in `wthb-pageinfo_ext.csv` kombiniert. `classify_prefix()` vergibt Kapitel-/Abschnitts-Präfixe. Es schreibt vier Outputs:

- `wthb-toc.wiki` — die MediaWiki-TOC-Quelle
- `wthb-toc.json` — die strukturierten Daten, die das Modul verbraucht
- `de.json` — die deutsche Sprachdatei für Weblate
- `wthb-toc.html` — eine gerenderte HTML-Kopie (legacy/parallel — der aktuelle Konsument rendert aus **JSON**)

## GenWiki-Template (pywikibot WRITE)

Schritte 3–4 wickeln das generierte TOC im MediaWiki-Template [**`Vorlage:WT-Verzeichnis-TOC`**](https://wiki.genealogy.net/Vorlage:WT-Verzeichnis-TOC) ein und schreiben es zurück:

- die `pagefromfile`-Datei kombiniert einen `<noinclude>`-Teil (`{{Dokumentation}}` + `[[Kategorie:Webtrees]]`) mit einem `<includeonly>`-Teil (`Stand: <datum>` + `<div class="wthbtoc">…</div>`).
- `pywikibot pagefromfile -force -pt:1 -summary:"Bot: Webtrees Handbuch Inhaltsverzeichnis aktualisiert"` führt den Write aus.

Schritt 5 verifiziert das Ergebnis, indem es das Template über die GenWiki-API (`action=parse&format=json`) neu parst und das HTML mit `jq -r '.parse.text["*"]'` extrahiert.

## Externes Repo, CI & Pages

Die zweite Hälfte der Pipeline (ab Schritt 6) befördert die strukturierten Daten aus dem Host heraus:




<pre class="mermaid">flowchart TB
    OUT[&#34;`📦 *Ausgaben*&lt;br/&gt;wthb-toc.json &#43; de.json`&#34;]
    DEP[&#34;`🚀 **wt-deploy-toc-lang.sh**`&#34;]

    subgraph EXTERNAL[&#34;🌐 Externe Infrastruktur&#34;]
        REPO[&#34;`📦 **linkenhancer-wthb-toc-lang**&lt;br/&gt;(Codeberg)`&#34;]
        META[&#34;`🔧 *tools/gen_meta.py*&lt;br/&gt;languages.json &#43; version.json`&#34;]
        CI[&#34;`⚙️ *CI regen-meta.yml*&lt;br/&gt;gen_toc_html.py`&#34;]
        PG[&#34;`🌐 **Codeberg Pages**`&#34;]
        WLB[&#34;`🌐 **Weblate** · linkenhancer/wthb-toc`&#34;]
        TNG[&#34;🗝 en.json · fr.json · …&#34;]
    end

    subgraph MODULE[&#34;📦 Modul (linkenhancer)&#34;]
        SVC[&#34;`**WthbTocService**`&#34;]
        DS[&#34;`💾 *data/…/wthb-toc-lang/*&lt;br/&gt;2-Layer-Cache`&#34;]
        RDR[&#34;`📄 **help-wthb-toc.phtml**&lt;br/&gt;TOC-Modal`&#34;]
    end

    OUT --&gt;|&#34;cp wthb-toc.json &#43; de.json&#34;| DEP
    DEP --&gt;|&#34;git add / commit / push&#34;| REPO
    REPO --&gt;|&#34;regen meta&#34;| META
    REPO --&gt; CI --&gt; PG
    REPO --&gt;|&#34;de.json (Source)&#34;| WLB
    WLB --&gt; TNG
    TNG --&gt;|&#34;[lang].json&#34;| REPO
    PG --&gt;|&#34;fetch JSON&#34;| MODULE
    SVC --&gt; DS --&gt; RDR

    classDef coreStyle fill:#ede7f6,stroke:#5e35b1,stroke-width:2px
    classDef okStyle fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px
    classDef queueStyle fill:#fff3e0,stroke:#e65100,stroke-width:2px

    class OUT okStyle
    class DEP,REPO,META,CI,SVC coreStyle
    class PG,TNG,DS,RDR okStyle
    class WLB queueStyle
</pre>

- **`wt-deploy-toc-lang.sh`** kopiert `wthb-toc.json` und `de.json` in das Repo `linkenhancer-wthb-toc-lang`, führt `tools/gen_meta.py` aus (regeneriert `languages.json` + `version.json`) und macht `git add/commit/push`. Es ist standalone aufrufbar und **skippt weich** (Warnung + `exit 0`), wenn Repo oder JSON fehlen, sodass es den `set -e`-Orchestrator nie abbricht.
- **Repo-CI** (`regen-meta.yml`) führt `gen_toc_html.py` aus und veröffentlicht auf **Codeberg Pages**.

## Weblate

Die `de.json` im Repo ist die **Quelle** der Weblate-Komponente **`wt-modules/linkenhancer-wthb-toc`**; die übrigen `[lang].json`-Dateien sind deren Übersetzungs-Ziele. Die Übersetzungen fließen zurück ins Repo und werden über Codeberg Pages ausgeliefert.

## Konsument (Modul)

Knapp — Details auf der [WTHB-Funktionsseite](../features/wthb) und der Seite [CLI-Skripte](cli-scripts):

- <a href="https://codeberg.org/bschwede/linkenhancer/src/branch/main/src/Services/WthbTocService.php" target="_blank" rel="noopener"><code>WthbTocService.php</code></a>
 holt die Sprach-JSON von Codeberg Pages und stellt sie über einen **zwei-Schichten-Cache** bereit.
- <a href="https://codeberg.org/bschwede/linkenhancer/src/branch/main/cli/refresh-wthb-toc.php" target="_blank" rel="noopener"><code>refresh-wthb-toc.php</code></a>
 (und `cli/validate-wthb-toc.php`) aktualisiert bzw. prüft diesen Cache, typischerweise per Cron.
- <a href="https://codeberg.org/bschwede/linkenhancer/src/branch/main/resources/views/help-wthb-toc.phtml" target="_blank" rel="noopener"><code>help-wthb-toc.phtml</code></a>
 rendert das TOC im Hilfe-Dialog.

## Konfiguration & Voraussetzungen

- `setenv.sh` — exportiert `PWB_PY`, `PWB_CONF`, `SCRIPTDIR`.
- pywikibot-Config — `user-config-test.py` / `user-config-prod.py`.
- `wthb-toc-lang.env` — `TOC_LANG_REPO=$HOME/dev/linkenhancer-wthb-toc-lang`, `TOC_LANG_DATADIR=$HOME/dev/wthb-toc-datadir`.
- Voraussetzungen: pywikibot, pandas, jq, python3.

## Ops & Caveats

- **Manuelle Bild-Nacharbeit** — Bilderverzeichnis und `Kategorie:Webtrees` müssen von Hand gepflegt werden.
- **`pagefromfile`-Login** — laut Code-Kommentar muss ggf. `site.login()` in `pagefromfile.py` eingefügt werden.
- **Soft-Skip im Deploy** — fehlendes Repo oder JSON ist eine Warnung, kein Fehler (hält `set -e` sicher).
