feat: lokales Google-Fonts-Hosting + "Lizenz upgraden"-button (v1.3.0)

- Lizenz-Tab: bei vollen Plaetzen erscheint ein "Lizenz upgraden"-Button
  (https://lucas-orth.de/wp-plugins/gdpr-content-blocker/) zusaetzlich zur
  domain-freigabe.
- Neues Feature "Schriften": Google Fonts lokal hosten (button-modell).
  Admin klickt "Jetzt herunterladen & einbinden" -> plugin scannt die seiten,
  laedt googleapis-CSS + gstatic-schriftdateien einmalig in den uploads-ordner,
  schreibt die pfade lokal um und tauscht sie per output-buffer im quelltext.
  Abgedeckt: <link>, inline-@import/url() UND @import/url() in gleicher-origin
  externen CSS-dateien (mit absolutierung der restlichen relativen pfade).
  preconnect/dns-prefetch zu google-font-hosts werden entfernt (kein IP-leak).
  Toggle zum aus/einschalten + "Lokale Schriften loeschen".
- i18n-pipeline robuster: build-en-mo.py nutzt jetzt translations-en.json
  (lookup per quell-string, reihenfolge-unabhaengig) und bricht mit liste ab,
  falls eine uebersetzung fehlt. Alle neuen strings DE/EN ergaenzt (139).
- version 1.3.0 (header + CB_VERSION).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
s4luorth
2026-06-08 07:16:19 +02:00
parent ca0f2f2c32
commit 377c64f8d0
10 changed files with 990 additions and 152 deletions

View File

@@ -0,0 +1,141 @@
{
"Ungültige Antwort vom Lizenzserver.": "Invalid response from the license server.",
"Keine Berechtigung.": "Insufficient permissions.",
"Bitte einen Lizenzschlüssel eingeben.": "Please enter a license key.",
"Lizenz erfolgreich aktiviert.": "License activated successfully.",
"Alle Plätze dieser Lizenz sind belegt. Geben Sie eine Domain frei, um diese Seite zu aktivieren.": "All seats for this license are in use. Release a domain to activate this site.",
"Aktivierung fehlgeschlagen.": "Activation failed.",
"Bitte eine gültige Domain zum Freigeben auswählen.": "Please select a valid domain to release.",
"Domain %s freigegeben und diese Seite aktiviert.": "Released %s and activated this site.",
"Lizenz nicht mehr gültig.": "License is no longer valid.",
"GDPR Content Blocker ist nicht lizenziert. Der Schutz bleibt aktiv, aber für Updates und Support bitte %s hinterlegen.": "GDPR Content Blocker is not licensed. Protection stays active, but please add a %s for updates and support.",
"Lizenzschlüssel": "License key",
"Aktiv": "Active",
"Ungültig": "Invalid",
"Alle Plätze belegt": "All seats in use",
"Nicht aktiviert": "Not activated",
"Status": "Status",
"Domain": "Domain",
"Belegte Domains": "Bound domains",
"Diese Lizenz ist bereits auf folgenden Domains aktiv. Entfernen Sie eine, um den Platz freizugeben – diese Seite wird anschließend automatisch aktiviert.": "This license is already active on the following domains. Remove one to free a seat — this site will then be activated automatically.",
"Diese Domain wirklich aus der Lizenz entfernen?": "Really remove this domain from the license?",
"Domain entfernen": "Remove domain",
"Aus Sicherheitsgründen verdeckt. Zum Ändern bitte zuerst deaktivieren.": "Hidden for security. To change it, deactivate first.",
"Lizenz deaktivieren": "Deactivate license",
"Erneut versuchen": "Try again",
"Lizenz aktivieren": "Activate license",
"Empfänger:": "Recipient:",
"Zweck:": "Purpose:",
"⚠ Datenübermittlung in ein Drittland außerhalb der EU/des EWR": "⚠ Data transfer to a third country outside the EU/EEA",
"Datenschutzerklärung des Anbieters": "Provider's privacy policy",
"%s jetzt laden": "Load %s now",
"Diesen Dienst künftig immer laden": "Always load this service from now on",
"Um diesen Inhalt von %s zu laden, ist Ihre Einwilligung erforderlich. Dabei werden personenbezogene Daten (z. B. Ihre IP-Adresse) an den Anbieter übertragen.": "Loading this content from %s requires your consent. Personal data (e.g. your IP address) will be transmitted to the provider.",
"Einwilligung für externe Inhalte widerrufen": "Withdraw consent for external content",
"Betrifft nur die Freigabe externer Einbettungen (z. B. Karten, Videos). Cookie-Einstellungen werden separat verwaltet.": "Affects only the release of external embeds (e.g. maps, videos). Cookie settings are managed separately.",
"Übermittlung in ein Drittland außerhalb der EU/des EWR": "Transfer to a third country outside the EU/EEA",
"Empfänger": "Recipient",
"Zweck": "Purpose",
"Setzt Cookies": "Sets cookies",
"Ja": "Yes",
"Nein": "No",
"Datenschutz": "Privacy policy",
"GDPR Content Blocker": "GDPR Content Blocker",
"Dienst wirklich entfernen?": "Really remove this service?",
"Neuer Dienst": "New service",
"Scanne Webseite …": "Scanning website …",
"Scan fehlgeschlagen:": "Scan failed:",
"Keine externen Einbindungen gefunden.": "No external resources found.",
"Anbieter / Host": "Provider / Host",
"Typ": "Type",
"Anzahl": "Count",
"Beispiel-URL": "Example URL",
"Aktion": "Action",
"abgedeckt": "covered",
"Drittanbieter": "third party",
"eigene Domain": "own domain",
"Als Dienst übernehmen": "Add as service",
"Vorlage übernehmen": "Use template",
"Vorlage verfügbar": "Template available",
"Gescannte Seiten:": "Scanned pages:",
"Gefunden auf": "Found on",
"Google Ireland Ltd., Irland / Google LLC, USA": "Google Ireland Ltd., Ireland / Google LLC, USA",
"Darstellung interaktiver Karten und Standortinformationen.": "Display of interactive maps and location information.",
"Einbettung und Wiedergabe von Videos.": "Embedding and playback of videos.",
"OpenStreetMap Foundation, Großbritannien": "OpenStreetMap Foundation, United Kingdom",
"Darstellung interaktiver Karten.": "Display of interactive maps.",
"Vimeo LLC, USA": "Vimeo LLC, USA",
"Einstellungen gespeichert.": "Settings saved.",
"Dienste": "Services",
"Scan": "Scan",
"Darstellung": "Appearance",
"Shortcodes": "Shortcodes",
"Lizenz": "License",
"Über das Plugin": "About the plugin",
"+ Leeren Dienst hinzufügen": "+ Add empty service",
"— Vorlage einfügen —": "— Insert template —",
"Dienste speichern": "Save services",
"Der Lizenzserver besucht Ihre Webseite und listet alle eingebundenen Drittanbieter-Ressourcen (iframes, Skripte, Schriften, Bilder, …) auf. So sehen Sie auf einen Blick, welche externen Dienste Sie blockieren sollten. Erfordert eine aktive Lizenz.": "The license server visits your website and lists all embedded third-party resources (iframes, scripts, fonts, images, …). This shows at a glance which external services you should block. Requires an active license.",
"Webseite scannen": "Scan website",
"Darstellung speichern": "Save appearance",
"Details anzeigen/ausblenden": "Show/hide details",
"Blocker aktiv/inaktiv": "Blocker on/off",
"Dienst entfernen": "Remove service",
"Anbietername": "Provider name",
"Erkennungsmuster (Domain/Pfad)": "Detection pattern (domain/path)",
"Empfänger (inkl. Land)": "Recipient (incl. country)",
"Datenschutz-URL des Anbieters": "Provider's privacy policy URL",
"Verarbeitungszweck": "Processing purpose",
"Individueller Platzhaltertext (leer = Standard)": "Custom placeholder text (empty = default)",
"Datenübermittlung in Drittland (außerhalb EU/EWR)": "Data transfer to a third country (outside EU/EEA)",
"Lädt externe Skripte": "Loads external scripts",
"Textfarbe Platzhalter": "Placeholder text color",
"Hintergrundfarbe Platzhalter": "Placeholder background color",
"Button: Hintergrundfarbe": "Button: background color",
"Button: Textfarbe": "Button: text color",
"Button Hover: Hintergrundfarbe": "Button hover: background color",
"Button Hover: Textfarbe": "Button hover: text color",
"Custom CSS": "Custom CSS",
"Wird nach den CSS-Variablen eingebunden und kann diese überschreiben. Tipp: denselben Präfix verwenden, z. B. .cb-blocker .cb-blocker__button { … }": "Loaded after the CSS variables and can override them. Tip: use the same prefix, e.g. .cb-blocker .cb-blocker__button { … }",
"CSS-Klassen:": "CSS classes:",
"Widerruf (Datenschutzerklärung)": "Withdrawal (privacy policy)",
"Rendert einen gut sichtbaren Link, der die Einwilligung für externe Einbettungen widerruft und die Seite neu lädt (Art. 7 Abs. 3 DSGVO). Betrifft NICHT die Cookie-Einwilligung eines separaten Cookie-Plugins. Optionen: text=\"…\", style=\"link|button\", note=\"yes|no\".": "Renders a clearly visible link that withdraws consent for external embeds and reloads the page (Art. 7(3) GDPR). Does NOT affect the cookie consent of a separate cookie plugin. Options: text=\"…\", style=\"link|button\", note=\"yes|no\".",
"Inhalt manuell blockieren": "Block content manually",
"Umschließt ein iframe und ersetzt es durch den Platzhalter des angegebenen Dienstes. Die ID ist der Anbietername in Kleinbuchstaben mit Bindestrichen (z. B. „Google Maps\" → google-maps).": "Wraps an iframe and replaces it with the placeholder of the given service. The ID is the provider name in lowercase with hyphens (e.g. \"Google Maps\" → google-maps).",
"Dienste-Übersicht (Datenschutzerklärung)": "Services overview (privacy policy)",
"Listet alle konfigurierten Dienste mit Empfänger, Drittland-Hinweis, Zweck und Datenschutz-Link auf. Ideal zum Einbinden in die Datenschutzerklärung (Art. 13 DSGVO).": "Lists all configured services with recipient, third-country note, purpose and privacy link. Ideal for inclusion in your privacy policy (Art. 13 GDPR).",
"Version %s": "Version %s",
"GDPR Content Blocker lädt externe Einbindungen (z. B. Google Maps, YouTube, OpenStreetMap, Vimeo) erst nach aktiver Einwilligung der Besucher. Vor dem Klick wird keine Verbindung zum Drittanbieter aufgebaut – es werden also keine personenbezogenen Daten (z. B. die IP-Adresse) übertragen. So lassen sich externe Inhalte DSGVO-konform einbinden, ohne ein schweres Consent-Tool.": "GDPR Content Blocker loads external embeds (e.g. Google Maps, YouTube, OpenStreetMap, Vimeo) only after the visitor actively consents. Before the click no connection to the third party is made — so no personal data (e.g. the IP address) is transmitted. This lets you embed external content in a GDPR-compliant way without a heavy consent tool.",
"Funktionen": "Features",
"Echtes Click-to-Load (kein vorab geladenes iframe)": "True click-to-load (no preloaded iframe)",
"Granulare Einwilligung pro Dienst": "Granular consent per service",
"Art.-13-konformer Platzhalter mit Empfänger, Zweck, Drittland-Hinweis und Datenschutz-Link": "Art.-13-compliant placeholder with recipient, purpose, third-country note and privacy link",
"Einfacher Widerruf per Shortcode (Art. 7 Abs. 3 DSGVO)": "Easy withdrawal via shortcode (Art. 7(3) GDPR)",
"Automatische Erkennung gängiger Anbieter + manueller Shortcode": "Automatic detection of common providers + manual shortcode",
"Rechtliches": "Legal",
"Impressum": "Imprint",
"Datenschutzerklärung": "Privacy policy",
"Hinweis: Dieses Plugin ist ein technisches Hilfsmittel und ersetzt keine Rechtsberatung. Für die rechtskonforme Konfiguration (Empfänger, Zwecke, Datenschutzerklärung) ist der Seitenbetreiber verantwortlich.": "Note: This plugin is a technical tool and does not constitute legal advice. The site operator is responsible for the legally compliant configuration (recipients, purposes, privacy policy).",
"Entwickelt von %s": "Developed by %s",
"Bitte zuerst eine Lizenz aktivieren (Tab „Lizenz\").": "Please activate a license first (\"License\" tab).",
"Unerwartete Antwort vom Lizenzserver.": "Unexpected response from the license server.",
"Lizenz upgraden": "Upgrade license",
"Schalten Sie weitere Domains frei, um diese Seite zusätzlich zu aktivieren – oder geben Sie unten eine bestehende Domain frei.": "Unlock more domains to additionally activate this site — or release an existing domain below.",
"Schriften": "Fonts",
"Schriften werden heruntergeladen …": "Downloading fonts …",
"Fehler beim Herunterladen:": "Download error:",
"Lokale Schriften wirklich löschen?": "Really delete the local fonts?",
"Upload-Verzeichnis konnte nicht erstellt werden.": "The upload directory could not be created.",
"Lokale Schriften gelöscht.": "Local fonts deleted.",
"%1$d Schrift-Stylesheet(s) und %2$d Schriftdatei(en) lokal gespeichert.": "%1$d font stylesheet(s) and %2$d font file(s) stored locally.",
"Bindet Google Fonts lokal ein: Das Plugin lädt die Schrift-Stylesheets und Schriftdateien einmalig herunter, speichert sie in Ihrem Uploads-Ordner und ersetzt die Pfade im Seitenquelltext. So wird beim Seitenaufruf keine Verbindung mehr zu Google aufgebaut (kein IP-Transfer) und die Schriften laden schneller.": "Hosts Google Fonts locally: the plugin downloads the font stylesheets and font files once, stores them in your uploads folder and replaces the paths in the page source. As a result no connection to Google is made on page load (no IP transfer) and fonts load faster.",
"Lokales Hosting": "Local hosting",
"Lokale Schriften ein/aus": "Local fonts on/off",
"Wenn aktiv, werden auf der Webseite die heruntergeladenen lokalen Schriften statt der Google-Pfade ausgeliefert.": "When enabled, the website serves the downloaded local fonts instead of the Google paths.",
"Speichern": "Save",
"Schriften herunterladen": "Download fonts",
"Jetzt herunterladen & einbinden": "Download & embed now",
"Lokale Schriften löschen": "Delete local fonts",
"Aktuell lokal: %1$d Stylesheet(s), %2$d Schriftdatei(en) – zuletzt aktualisiert am %3$s.": "Currently local: %1$d stylesheet(s), %2$d font file(s) — last updated on %3$s.",
"Hinweis: Gescannt werden die Startseite und einige Unterseiten. Falls auf einzelnen Seiten weitere Google Fonts vorkommen, führen Sie die Aktion nach Inhaltsänderungen erneut aus.": "Note: the home page and a few sub-pages are scanned. If individual pages contain additional Google Fonts, run the action again after content changes."
}