i18n Manager — Technische Doku

Technische Dokumentation

Architektur, Datenmodell, API, Front-End-Lokalisierung und Tooling-Referenz für den i18n Manager.

Architektur-Überblick

Der i18n Manager ist eine klassische, serverseitig gerenderte PHP-Anwendung mit einer PostgreSQL-Datenbank und einem Front End im Stil einer Single-Page-Anwendung auf Basis von jQuery/Foundation. Es gibt keinen Build-Schritt und kein Framework — der Browser lädt index.php, das über AJAX mit einer Reihe kleiner PHP-Endpunkte unter /api/ kommuniziert. Jeder Endpunkt verbindet sich über einen schlanken prozeduralen Wrapper direkt mit PostgreSQL und gibt JSON zurück.

Browser (index.php + jQuery)
   │  AJAX (GET/POST)
   ▼
/api/*.php  ──►  classes/class_pgsql_data.php  ──►  PostgreSQL
   │
   └─ JSON responses

Technologie-Stack

SchichtTechnologie
ServerPHP (prozedural), pg_*-Erweiterung
DatenbankPostgreSQL (gehostet auf Supabase)
Front-End-BibliothekenjQuery 3.6, Foundation Sites 6.7.5, Font Awesome 6.4 (über CDN)
Stylingincludes/app.css
ToolingNode.js (der Schlüssel-Scanner); keine npm-Abhängigkeiten zur Laufzeit
API-DokumentationOpenAPI 3.0, Swagger UI, ReDoc, Postman-Collection

Verzeichnisstruktur

i18n_management/
├── index.php                  # Dashboard-SPA (Markup + jQuery-App)
├── pages/                     # Eigenständige HTML-Seiten (Doku + API-UIs)
│   ├── swagger.html           # Swagger UI (interaktive API-Doku)
│   ├── redoc.html             # ReDoc (schreibgeschützte API-Doku)
│   ├── user-guide.html        # Endbenutzer-Dokumentation (+ .de.html)
│   ├── technical.html         # Diese Seite (+ .de.html)
│   └── integration.html       # Integrationsleitfaden (+ .de.html)
├── api/
│   ├── languages_list.php
│   ├── language_toggle.php
│   ├── translations_list.php
│   ├── translations_i18n.php  # flache { key: {lang: value} }-Map
│   ├── translations_export.php
│   ├── translation_key_save.php
│   ├── translations_import.php
│   ├── translation_key_delete.php
│   └── openapi.json           # OpenAPI-3.0-Spezifikation
├── classes/
│   └── class_pgsql_data.php   # PostgreSQL-Zugriffs-Wrapper
├── includes/
│   ├── app.css                # Dashboard-Styles
│   └── docs.css               # Dokumentations-Styles
├── tools/
│   └── scan_i18n_keys.js      # Markup-Scanner + Seed-Generator
├── hold_files/                # Referenz-SQL/JSON (Schema, Seeds, i18n.json)
├── seeds/                     # Generierte Seed-Ausgabe (optional)
└── postman/                   # Postman-Collection

Datenbankschema

Definiert in hold_files/schema.sql. Vier Tabellen plus Trigger und Indizes.

languages

SpalteTypAnmerkungen
codeCHAR(2)PK — ISO-639-1-Code (en, de…)
nameVARCHAR(64)Anzeigename
is_activeBOOLEANStandard TRUE
created_atTIMESTAMPTZStandard NOW()

translation_keys

SpalteTypAnmerkungen
idSERIALPK
keyVARCHAR(255)UNIQUE — z. B. home.welcome
namespaceVARCHAR(64)GENERATED ALWAYS AS split_part(key,'.',1) STORED
descriptionTEXTOptionaler Hinweis für Übersetzer
contains_htmlBOOLEANStandard FALSE
created_at / updated_atTIMESTAMPTZupdated_at wird per Trigger gepflegt

translations

SpalteTypAnmerkungen
idSERIALPK
key_idINTFK → translation_keys, ON DELETE CASCADE
language_codeCHAR(2)FK → languages, ON DELETE RESTRICT
valueTEXTDie übersetzte Zeichenkette
is_reviewedBOOLEANStandard FALSE
created_at / updated_atTIMESTAMPTZPer Trigger gepflegt
UNIQUE (key_id, language_code) — eine Zeile pro Schlüssel × Sprache; ermöglicht Upserts über ON CONFLICT.

translation_audit

Nur-anhängendes Protokoll, das von einem AFTER UPDATE-Trigger auf translations geschrieben wird, sobald sich ein Wert ändert: speichert key_id, language_code, old_value, new_value, changed_by, changed_at.

Trigger & Indizes

Datenzugriffsschicht

classes/class_pgsql_data.php ist ein prozeduraler Wrapper um die PHP-pg_*-Funktionen. Endpunkte binden ihn über $_SERVER['DOCUMENT_ROOT'] ein und nutzen diese Hilfsfunktionen:

FunktionZweck
DB_Connect_Direct($write)Öffnet eine Verbindung (Lese-/Schreibzugriff oder schreibgeschützt).
DB_Query($conn, $sql)Führt eine literale Abfrage aus.
DB_QueryParams($conn, $sql, $params)Parametrisierte Abfrage ($1, $2…) — hiermit lässt sich SQL-Injection vermeiden.
DB_FetchAssoc / DB_FetchAllEine Zeile / alle Zeilen als assoziative Arrays abrufen.
DB_Begin / DB_Commit / DB_RollbackTransaktionssteuerung (genutzt von Speichern & Import).
DB_AffectedRows / DB_FreeResult / DB_CloseZeilenanzahl / Aufräumen.
Booleans: PostgreSQL gibt Booleans als die Zeichenketten 't'/'f' zurück. Endpunkte normalisieren diese zu echten Booleans, bevor sie als JSON kodiert werden (z. B. $lang['is_active'] === 't').

API-Endpunkte

Alle Endpunkte geben JSON zurück (außer dem Export-Download). Das vollständige Request-/Response-Schema befindet sich in openapi.json und ist über Swagger / ReDoc durchsuchbar.

MethodeEndpunktParameterZweck
GETlanguages_list.phpSprachen auflisten.
POSTlanguage_toggle.phpcode, is_activeEine Sprache aktivieren/deaktivieren.
GETtranslations_list.phpnamespace, search, page, limitPaginierte Schlüssel + Übersetzungen.
GETtranslations_i18n.phpnamespace, search, formatFlache {key:{lang:value}}-Map (json oder js).
GETtranslations_export.phplanguage*, format, namespace, searchHerunterladbares JSON/CSV.
POSTtranslation_key_save.phpid, key, description, contains_html, mark_reviewed, translationsEinen Schlüssel anlegen/aktualisieren (transaktionaler Upsert).
POSTtranslations_import.phpdata, overwrite, is_reviewedEine JSON-Map per Massenimport einlesen.
POSTtranslation_key_delete.phpidEinen Schlüssel löschen (mit Kaskadierung).

* erforderlich

API-Konventionen

Front-End-Lokalisierungs-Engine

Das Dashboard lokalisiert seine eigene Oberfläche aus denselben Daten, die es verwaltet. Beim Laden ruft es translations_i18n.php nach state.i18n ab (eine flache {key:{lang:value}}-Map), baut den Sprachumschalter aus den aktiven Sprachen auf und wendet die Übersetzungen an.

UI-Elemente nehmen über Datenattribute teil:

AttributEffekt
data-i18n="key"Setzt den Text des Elements.
data-i18n-html="key"Setzt das innerHTML des Elements (für Werte, die Markup enthalten).
data-i18n-placeholder="key"Setzt den placeholder eines Eingabefelds.

applyI18n(lang) durchläuft jedes markierte Element, schlägt state.i18n[key][lang] nach und aktualisiert es; fehlende Schlüssel/Sprachen fallen auf das vorhandene (englische) Markup zurück. Die ausgewählte Sprache wird in localStorage gespeichert und auf <html lang> widergespiegelt.

Die schlüsselweise automatische Übersetzung im Dialog Hinzufügen/Bearbeiten ruft für jede Zielsprache Googles Endpunkt translate.googleapis.com/translate_a/single?client=gtx auf.

Schlüssel-Scanner — tools/scan_i18n_keys.js

Ein abhängigkeitsfreies Node-Skript, das Quelldateien nach data-i18n*-Attributen durchsucht, ermittelt, welche Schlüssel neu sind, und einfügefertiges Massenimport-JSON sowie idempotentes Seed-SQL generiert — optional unter maschineller Übersetzung des Quelltexts in jede Sprache.

# New keys vs. the seed/reference files
node tools/scan_i18n_keys.js

# Diff against the LIVE database instead of seed files
node tools/scan_i18n_keys.js --endpoint http://localhost/api/translations_i18n.php

# Machine-translate the source text into all languages
node tools/scan_i18n_keys.js --translate

# Write seeds/new_keys.{json,sql} instead of printing
node tools/scan_i18n_keys.js --out seeds

# Other flags: --all (ignore existing), --root DIR, --langs de,fr,es

Seeds & Referenzdateien

DateiZweck
hold_files/schema.sqlVollständiges Datenbankschema (Tabellen, Trigger, Indizes).
hold_files/seed_translations.sqlDemo-Inhaltsschlüssel (nav.home, home.welcome…).
hold_files/seed_ui_chrome.sqlSchlüssel der Oberflächen-Chrome (Tabs, Schaltflächen, Tabellenüberschriften) in allen Sprachen.
hold_files/i18n.jsonReferenz-Flachmap, die die Exportform veranschaulicht.

Seed-Dateien verwenden einen CTE (WITH ins_keys AS (INSERT … RETURNING)) und ON CONFLICT … DO UPDATE, sodass sie idempotent und gefahrlos erneut ausführbar sind.

API-Dokumentations-Artefakte

Einrichtung & Deployment

  1. Stellen Sie das Projekt-Stammverzeichnis mit PHP bereit (die pg_*-Erweiterung muss aktiviert sein). Die Anwendung geht davon aus, dass sie im Domain-Stammverzeichnis bereitgestellt wird — sie verweist auf /includes/, /classes/, /api/ und $_SERVER['DOCUMENT_ROOT'].
  2. Stellen Sie eine PostgreSQL-Datenbank bereit und wenden Sie hold_files/schema.sql an.
  3. Seeden Sie die Referenzdaten: seed_translations.sql und/oder seed_ui_chrome.sql.
  4. Konfigurieren Sie die Datenbank-Verbindungsdetails in classes/class_pgsql_data.php (siehe Sicherheitshinweis unten).
  5. Öffnen Sie index.php. Die CDN-Assets (Foundation, jQuery, Font Awesome, Swagger/ReDoc) erfordern Internetzugang.

Sicherheitshinweise

Hartcodierte Zugangsdaten: Datenbank-Host/-Benutzer/-Passwort sind derzeit fest in classes/class_pgsql_data.php codiert. Verlagern Sie sie in Umgebungsvariablen und rotieren Sie das Passwort — alles, was in git committet wurde, sollte als kompromittiert betrachtet werden.