Konfiguration¶
Extension-Konfiguration¶
Admin Tools → Einstellungen → Extension-Konfiguration → nt_lingua öffnen.
| Einstellung | Standard | Beschreibung |
|---|---|---|
translator |
LLM (nt_ai) | Übersetzungs-Backend für DOM-Sprachen: LLM (nt_ai) verwendet den in nt-ai konfigurierten Provider; DeepL spricht die DeepL-API direkt an. |
deepLApiKey |
(leer) | DeepL-API-Key. Leer lassen, um LLM zu verwenden. Unterstützt %env(VAR)%. |
deepLEndpoint |
https://api-free.deepl.com/v2 |
DeepL-API-Endpunkt. Free-Tier: https://api-free.deepl.com/v2, Pro-Abo: https://api.deepl.com/v2. |
autoTranslateOnSave |
an | Beim Speichern automatisch übersetzen. Für Massenvorgänge (Import, Migration) ausschalten. |
Öffentliche Endpunkte absichern¶
Anonyme Besucher lösen Anbieter-Aufrufe auf zwei Wegen aus: über die POST-API /nt-lingua/transform (DOM-Übersetzung, Einfache Sprache je Inhaltselement) und über den Seitenaufruf mit ?ntlingua=einfache|leichte bzw. dem gleichnamigen Cookie. Beide Wege teilen sich dieselben Budgets. Gezählt werden nur echte Anbieter-Aufrufe, und jeder wird unmittelbar vor dem Senden reserviert: der LLM-Fallback nach DeepL-HTTP-456, jeder Teilblock eines Stapels und jede Wiederholung (ein LLM-Teilblock nach leerer Antwort, jede Hälfte eines LLM-Teilblocks nach einer Antwort falscher Länge, eine DeepL-Anfrage nach HTTP 429). Ohne verbleibendes Budget wird nichts wiederholt. Cache-Treffer sind frei.
| Einstellung | Standard | Beschreibung |
|---|---|---|
rateLimitRequestsPerMinute |
60 | Anfragen pro Minute und Client an der POST-API. |
rateLimitCharsPerHour |
200000 | Zeichen pro Stunde und Client (IPv4-Adresse bzw. IPv6-/64-Netz). |
rateLimitGlobalCharsPerHour |
500000 | Zeichen pro Stunde für alle anonymen Aufrufe zusammen. Nicht durch IP-Wechsel umgehbar. |
rateLimitGlobalCharsPerDay |
2000000 | Zeichen pro Tag für alle anonymen Aufrufe zusammen. |
maxCharsPerRequest |
50000 | Höchstzahl Zeichen je DOM-Übersetzungsanfrage. |
maxCharsPerString |
8000 | Höchstzahl Zeichen je Textsegment; längere Segmente werden verworfen. |
maxConcurrentProviderRequests |
4 | Anonyme Requests, die gleichzeitig DeepL oder das Sprachmodell ansprechen dürfen, für die ganze Installation. Weitere erhalten HTTP 503 mit Retry-After; Cache-Treffer brauchen keinen Platz. 0 schaltet die Begrenzung ab. |
concurrencySlotTimeout |
120 | Sekunden, nach denen ein nie freigegebener Platz (abgestürzter oder abgebrochener Request) wieder als frei gilt. Länger als die langsamste erwartete Übersetzung wählen. |
domTranslationCacheOnly |
aus | DOM-Übersetzung öffentlich nur aus dem Cache. Neue Segmente übersetzt dann ausschließlich der DOM-Warmup (ntlingua:warmup-dom), der die echte Website abruft. Empfohlen, sobald der Warmup-Task regelmäßig läuft. |
triggerMode |
any |
Was auf dem Server Einfache/Leichte Sprache auslöst: any = Parameter ?ntlingua= oder Cookie (wie bisher), cookie = nur das Cookie (gefolgte Links lösen nichts aus), signed = nur ein vom Widget beim Server abgeholtes, signiertes Cookie. |
botProtection |
an | Such- und KI-Crawler, HTTP-Bibliotheken und Abrufe ohne Browser-Kennung lösen keine Umwandlung aus und bekommen bei der DOM-Übersetzung nur Cache-Treffer. |
Crawler (seit 1.4.0): Eine Seite mit ?ntlingua= trägt X-Robots-Tag: noindex, nofollow, eine umgewandelte Seite zusätzlich Cache-Control: private, no-store. Hängt Ihre Website den Parameter an Links an (etwa über config.linkVars), nehmen Sie ihn dort heraus – nt-lingua selbst tut das nicht. Für öffentliche Websites empfohlen: triggerMode = signed.
Bereiche ausschließen (seit 1.4.0): Neben translate="no" im Markup nimmt lib.ntLinguaExclude.value = .social-wall, #chat-widget (CSS-Selektoren, im Setup der Website) Bereiche von der DOM-Übersetzung aus.
Protokoll: Cache-Treffer stehen je Tag und Sprache als Aktion cache im Log (chars_in = Zeichen, chars_out = Segmente). Als Zeichen der Übersetzungen zählt, was tatsächlich an den Anbieter ging – Leerraum zusammengefasst, Texte ohne Buchstaben gar nicht.
Ist ein Budget erschöpft, antwortet die API mit HTTP 429, sind alle Plätze belegt, mit HTTP 503; vorhandene Cache-Treffer liefert sie in beiden Fällen trotzdem aus. Der GET-Weg zeigt nicht vereinfachte Absätze im Original. Backend, CLI und Scheduler unterliegen diesen Grenzen nicht.
Bewusst akzeptierte Einschränkung, solange domTranslationCacheOnly aus ist
Die DOM-Übersetzung nimmt gerenderte Segmente an (Textknoten, Attribute, Titel, nachgeladene Inhalte), die nicht als Datensatz existieren. Mit domTranslationCacheOnly aus — der Voreinstellung — kann jeder Aufrufer beliebigen Text auf Kosten des Betreibers übersetzen lassen, bis zur Grenze der Budgets oben. Die Budgets deckeln die Kosten, die Plätze die gleichzeitige Last; keines von beiden bindet den Text an die Inhalte der Website. Außerdem kann ein Aufrufer das globale Budget absichtlich aufbrauchen; andere Besucher erhalten dann bis zum Ende des Zeitfensters keine neuen Übersetzungen (Cache-Treffer funktionieren weiter). Das ist eine akzeptierte Einschränkung der Standardkonfiguration, keine Behebung: Schließen lässt sie nur domTranslationCacheOnly — mit dem Preis, dass neue Texte erst nach dem nächsten DOM-Warmup übersetzt erscheinen.
Weitere Schutzregeln:
- Zugriff wie im Frontend: Die POST-API liest Inhaltselemente nur, wenn das Frontend ihre Seite dem Besucher zeigen würde — Seite und Rootline werden auf versteckt, Start-/Stoppzeit, Zugriffsgruppen und „Auf Unterseiten ausdehnen" geprüft, außerdem Zugehörigkeit zur aufgerufenen Site und Sprache. Inhalte auf Ordnern (Sysfolder) werden nicht ausgeliefert.
- Seitenbindung: Eine DOM-Übersetzung muss die UID einer für den Besucher erreichbaren Seite der Site mitschicken (
window.ntLinguaPageUidbzw.data-page-uid), sonst HTTP 400. - Ausgabe: Antworten des Anbieters gelten als nicht vertrauenswürdig. HTML-Quellen werden immer mit einer Allowlist (typo3/html-sanitizer) bereinigt, reine Textquellen liefern reinen Text ohne Tags. Das gilt auch für bestehende Cache-Einträge, die bei jeder Ausgabe erneut bereinigt werden.
TypoScript-Einstellungen¶
plugin.tx_ntlingua.settings {
sourceLanguage = de
translator = llm
offerEinfache = 1
offerLeichte = 0
}
| Einstellung | Standard | Werte | Beschreibung |
|---|---|---|---|
sourceLanguage |
de |
ISO 639-1 | Sprache des Original-Seiteninhalts. Wird bei jedem Übersetzungsaufruf als Quellsprache übergeben. |
translator |
llm |
llm, deepl |
Übersetzungs-Backend für DOM-Sprachen. Muss mit dem TranslatorInterface-Alias in Services.yaml übereinstimmen. |
offerEinfache |
1 |
0 / 1 |
Option „Einfache Sprache" im Sprachwähler anzeigen. |
offerLeichte |
0 |
0 / 1 |
Option „Leichte Sprache" anzeigen. Nur aktivieren, wenn ein Disclaimer sichtbar ist — die Ausgabe ist ein KI-Entwurf und wurde nicht von einer zertifizierten Fachkraft geprüft. |
Sprachkonfiguration¶
Configuration/Languages.php definiert die verfügbaren Sprachen und ihren Modus:
return [
'en' => [
'name' => 'English',
'rtl' => false,
'mode' => 'native',
'sysLanguageUid' => 1,
'url' => '/en/',
],
'fr' => ['name' => 'Français', 'rtl' => false, 'mode' => 'dom'],
'ar' => ['name' => 'العربية', 'rtl' => true, 'mode' => 'dom'],
];
Feldreferenz:
| Feld | Pflicht | Beschreibung |
|---|---|---|
name |
Ja | Anzeigename im Sprachwähler. |
rtl |
Ja | true für Rechts-nach-links-Schriften (Arabisch, Hebräisch, Persisch). Setzt dir="rtl" und spiegelt das Layout. |
mode |
Ja | native oder dom — siehe Tabelle unten. |
sysLanguageUid |
nur native |
UID der TYPO3-Site-Sprache. Nachschlagen unter Sites → Site → Sprachen. |
url |
nur native |
URL-Präfix aus der TYPO3-Site-Konfiguration (z. B. /en/). Muss mit dem base-Feld der Site-Sprache übereinstimmen. |
Modus:
| Modus | Beschreibung |
|---|---|
native |
Echtes TYPO3-l10n-Overlay — server-gerendert, indexierbar, eigene URL, hreflang |
dom |
Client-seitige DOM-Ersetzung — sofort, nicht indexiert, kein Seitenneulade |
Site-Konfiguration (Backend)¶
Unter Sites → Konfiguration → Tab NT Lingua können die angebotenen DOM-Sprachen pro Site ausgewählt werden — ohne Languages.php anzupassen. Ist die Auswahl leer, werden alle mode: dom-Einträge aus Languages.php verwendet.
Übersetzungs-Backend¶
LLM (Standard)¶
Verwendet den in netthinks/nt-ai konfigurierten Provider. Kein zusätzlicher API-Key erforderlich.
In Configuration/Services.yaml:
Netthinks\NtLingua\Translator\TranslatorInterface:
alias: Netthinks\NtLingua\Translator\LlmTranslator
DeepL¶
Netthinks\NtLingua\Translator\TranslatorInterface:
alias: Netthinks\NtLingua\Translator\DeepLTranslator
Netthinks\NtLingua\Translator\DeepLTranslator:
arguments:
$apiKey: '%env(NTLINGUA_DEEPL_KEY)%'
Umgebungsvariable setzen:
DeepL Free API — Zeichenlimit
Das Free-Tier erlaubt 500.000 Zeichen/Monat. Bei Überschreitung (HTTP 456) wechselt die Extension automatisch auf den LLM-Übersetzer (via nt-ai) — für alle weiteren Anfragen im laufenden Monat. Rate-Limit-Antworten (HTTP 429) werden bis zu dreimal mit exponentiellem Backoff (5 / 10 / 20 s) wiederholt. Bei anonymen Requests wird jede Wiederholung vorher gegen das öffentliche Budget reserviert; ohne verbleibendes Budget gibt es weder Wiederholung noch Wartezeit.
Glossar¶
Einträge in der TYPO3-Listenansicht pflegen, Datensatztyp NT Lingua – Glossar. Der Ablageort ist frei wählbar — das Glossar wird global gelesen (kein pid-Filter), Einträge dürfen auf Root-Level (pid=0) und auf jedem Seitentyp liegen. Der Übersichtlichkeit halber alle Einträge an einem Ort halten (z. B. ein SysOrdner oder die Root-Seite).
target_lang |
mode |
Verhalten |
|---|---|---|
fr |
ignore |
Begriff für Französisch unverändert lassen |
* |
ignore |
Begriff für alle Sprachen ausschließen |
fr |
fixed |
Begriff immer durch target_term ersetzen |
* |
fixed |
Ersetzung für alle Sprachen |
Tip
Für Markennamen in Fließtext ist <span translate="no">Marke</span> zuverlässiger als Glossar-Einträge, da der Glossar-Check nur auf ganze Text-Knoten angewandt wird.
Inhalte von der Übersetzung ausschließen¶
<!-- Element und alle Kindelemente ausschließen: -->
<span translate="no">Net.Thinks</span>
<div data-nt-notranslate>Dieser Block bleibt unübersetzt</div>
Immer ausgeschlossene HTML-Tags: <script>, <style>, <code>, <pre>, <noscript>.
KI-Prompts¶
Die Ausgabe der Einfachen/Leichten Sprache kann durch Bearbeiten folgender Dateien angepasst werden:
Resources/Private/Prompts/einfache.txt— Einfache SpracheResources/Private/Prompts/leichte.txt— Leichte Sprache
Die Prompts müssen ausschließlich HTML mit <p>, <ul>/<li>, <h2>, <strong>, <a href> ausgeben. Fakten, Zahlen und Namen müssen unverändert bleiben.