STANDARD-TEXTE IN WORDPRESS ANPASSEN

WordPress mit seiner grossen Auswahl an Themes (wir verwenden OceanWP) und Plugins (wir verwenden v.a. Elementor Pro) lässt einiges zu bezüglich individueller Konfiguration der Website. Trotzdem gibt es einige Texte, die man nicht mit Online-Customizing anpassen kann. Hier, im Input-Bereich für den Post-Kommentar, konnten wir keinen einzigen selber anpassen:

Einige Texte bleiben sogar Englisch, obwohl wir die Seitensprache auf Deutsch (Schweiz) umgestellt haben. Nun konnten wir in Erfahrung bringen, dass WordPress für multilinguale Seiten GNU gettext verwendet. Dies ist ein Standard, der sehr breit auf verschiedenen Plattformen und in vielen Programmiersprachen für das Umsetzen von übersetzen Texten verwendet wird. Dazu werden Files verwendet, welche im binären Format die Mapping-Tabelle enthalten und deren Name normalerweise den Ziel-Sprachcode und die Endung .mo enthält. Im Verzeichnis wp-content/themes/oceanwp/languages haben wir ein File de_DE.mo gefunden, aber kein de_CH.mo. Schnell das deutsche kopiert auf den schweizerischen Namen, und schon sind ein paar weitere Texte übersetzt. Einige Übersetzungen fehlen aber noch, ausserdem passen uns nicht alle deutschen Texte. Den Quelltext zum .mo – File findet man im entsprechenden .po – File. Dieses hat eine einfache Struktur, hier ein Ausschnitt:
#: inc/oceanwp-strings.php:42
msgid "Post Comment"
msgstr ""

#: inc/oceanwp-strings.php:43
msgid "Name (required)"
msgstr "Name (erforderlich)"

#: inc/oceanwp-strings.php:44
msgid "Email (required)"
msgstr "E-Mail (erforderlich)"

Wir haben einige fehlende Texte übersetzt und einige unpassende geändert und jeweils bei msgstr eingetragen. Mit
    msgfmt -o de_CH.mo de_DE.po
haben wir ein neues deutsch-schweizerisches File erzeugt. Nun wurden alle Texte bis auf einen deutsch angezeigt. Aber: bei einem nächsten Update des Theme könnte das File überklatscht werden, und damit wäre unsere Mühe umsonst.

Für solche Zwecke haben wir ein „Child Theme“ angelegt. Normalerweise kann man eine entsprechende Vorlage beim Theme-Hersteller beziehen. Wir haben diese bei uns nach wp-content/themes/oceanwp-child kopiert. Es enthält im Wesentlichen die Files functions.php und style.css, ausserdem das Bildli screenshot.png, damit man das Theme in der WordPress-Administration auswählen kann, was wir dann auch getan haben.

Nun haben wir unter oceanwp-child das Verzeichnis languages angelegt und dorthin unser de_CH.mo kopiert. Nun müssen wir noch dafür sorgen, dass dieses Übersetzungsfile auch verwendet wird. Dazu machen wir im File functions.php folgenden Eintrag:

function child_theme_locale() {
    load_child_theme_textdomain( 'oceanwp', get_stylesheet_directory() . '/languages' );
}
add_action( 'after_setup_theme', 'child_theme_locale' );
Dies steht (fast) so in der Anleitung von OceanWP, nur dass sie den Domain-Namen dort fälschlicherweise mit 'ocean' statt 'oceanwp' angegeben haben. Your comment here… haben wir zwar im File übersetzt, aber er wurde immer noch original angezeigt. Ausserdem: Sind wir mit unseren Besuchern per Sie? Wir sind auch nicht mit jedem per Du … Also wollten wir Texte wie Schreiben Sie einen Kommentar „anrede-neutral“ halten. Im Original Englisch war das ja kein Problem … Viele Texte werden über den Standard (nicht Theme) von WordPress übersetzt. Man findet die Files unter wp-content/languages, auch de_CH.mo und de_CH.po. Es ist aber knifflig, ein allfällig geändertes Übersetzungsfile für die Default-Texte im Child-Theme unterzubringen, vor allem wollten wir nicht das ganze File nehmen, sondern nur die paar wenigen Texte, die wir anders übersetzt haben wollten, damit bei einem Update mit allfällig neuen Texten diese automatisch verwendet werden. Wir haben somit das Programm dazu gebracht, dass bei jedem gettext-Aufruf (der die entsprechende Übersetzung sucht) immer noch unsere eigene Übersetzungsfunktion aufgerufen wird und unsere wenigen Änderungen angebracht werden. Wiederum im functions.php im Child haben wir Folgendes eingefügt (Ausschnitt):
function translate_default_strings( $translated, $untranslated, $domain ) {
   switch ( $domain ) {
      case 'default' :
         switch ( $untranslated ) {
            case 'Leave a Reply' :
            case 'Leave a Comment' :
               $translated = 'Hier Kommentar schreiben';
               break;
            case 'Your comment is awaiting moderation. This is a preview, your comment will be visible after it has been approved.' :
               $translated = 'Kommentar wartet auf die Moderation. Dies ist eine Vorschau, der Kommentar wird sichtbar, nachdem er genehmigt wurde.';
               break;
            // etc, hier folgen weitere Uebersetzungen
         }
         break;
      case 'oceanwp' :
         switch ( $untranslated) {
            case 'Your comment here...' :
               $translated = 'Hier Kommentar...';
               break;
         }
         break;
   }
   return $translated;
}
add_filter( 'gettext', 'translate_default_strings', 999, 3 );
Die msgid der untranslated-Texte haben wir im de_CH.mo gefunden, indem wir nach dem entsprechenden übersetzten deutschen Text (msgstr) gesucht haben. Nun wird endlich auch das Your comment here… übersetzt. Warum das vorher nicht der Fall war, haben wir nicht unmittelbar herausgefunden, aber nun, da es funktioniert, wollen wir nicht grübeln. Der Nachteil dieser Lösung ist, dass nun bei jeder Übersetzung unsere Funktion aufgerufen wird, was natürlich angesichts der paar wenigen Texte nicht effizient ist. Wir haben aber keinen Einfluss auf die Laufzeit festgestellt. Bei WordPress werden ohnehin bei jedem Seitenaufruf eine Unmenge von Funktionen aufgerufen, da spielt eine mehr oder weniger auch keine Rolle mehr.

Eine Schönheitsoperation 

Nun gefällt uns der POST COMMENT Button noch nicht so richtig. Übersetzen konnten wir ihn schliesslich, aber das WordPress-Blau hätten wir gerne durch unser eigenes Blau ersetzt. Und alles in Grossbuchstaben? Das muss doch nicht so schreierisch sein. Wo werden diese Attribute gesetzt? Dies herauszufinden ist mit den meisten Browsern nicht so schwierig. Sie verfügen über einen Entwicklermodus, hier das Beispiel mit Google Chrome:
Einfach mit der rechten Maustaste auf das Objekt klicken, „Untersuchen“ auswählen. Die Sünder sind die Attribute background-color und text-transform. Mit der Maus über style.min.css fahren, und der genaue Pfad des Theme-Stylesheet erscheint. Wir nehmen aber die Variante ohne das min, diese ist übersichtlicher. Dort kopieren wir den entsprechenden Abschnitt heraus – den Abschnitt mit :hover nicht vergessen. Wahrscheinlich würde der Fall input[type="submit"] reichen, wir nehmen aber alles, da ähnliche Objekte/Buttons bei uns auch unsere eigenen Attribute haben sollen.
Im Verzeichnis des Child Theme gibt es ein eigenes style.css, andernfalls legen wir eines an. Dort fügen wir den kopierten Text ein und löschen alles, was wir nicht übersteuern wollen und passen den Rest nach unseren Bedürfnissen an. Schliesslich sollen die übrigen Attribute immer noch vom Original kommen und bei Updates entsprechend angepasst werden. Das sieht bei uns so aus:
input[type="button"],
input[type="reset"],
input[type="submit"],
button[type="submit"],
.button,
body div.wpforms-container-full .wpforms-form input[type=submit],
body div.wpforms-container-full .wpforms-form button[type=submit],
body div.wpforms-container-full .wpforms-form .wpforms-page-button {
  background-color: #3BACDB;
  color: #fff;
  text-transform: none;
}
Entsprechend wird mit dem :hover – Fall vorgegangen.
Wahrscheinlich funktioniert jetzt schon alles, mit dem richtigen Blau und in Gross-/Kleinschrift. Möglicherweise müssen wir aber noch dafür sorgen, dass unser style.css auch geladen wird. Dabei muss sichergestellt werden, dass zuerst das Stylesheet des Parent geladen wird und danach unser eigenes. Im function.php in unserem Child Theme gibt es dazu folgenden Abschnitt:
function oceanwp_child_enqueue_parent_style() {
   $theme   = wp_get_theme( 'OceanWP' );
   $version = $theme->get( 'Version' );
   wp_enqueue_style( 'child-style', get_stylesheet_directory_uri() . '/style.css', array( 'oceanwp-style' ), $version );
}
add_action( 'wp_enqueue_scripts', 'oceanwp_child_enqueue_parent_style' );
Dies kann je nach Theme unterschiedlich aussehen, am besten schaut man beim Anbieter nach. Als allgemeine Lösung haben wir dazu unterschiedliche Vorschläge gefunden, z.B. bei die-netzialisten.de:
function child_theme_styles() {
   wp_enqueue_style( 'parent-style',get_template_directory_uri() . '/style.css' );
   wp_enqueue_style( 'child-theme-css', get_stylesheet_directory_uri() . '/style.css' , array('parent-style'));
}
add_action( 'wp_enqueue_scripts', 'child_theme_styles' );

Dies würde bei uns wohl nicht 1:1 funktionieren, da bei unserem Theme die Stylesheets nicht unter dem template_directory_uri zu finden sind.

Nun sieht der Kommentar-Input bei uns so aus (die Textübersetzungen sind provisorisch):

Eine weitere Schönheitsoperation

Eigentlich wollten wir für unsere Website eine feine Schriftart mit kleiner Laufweite verwenden, am liebsten das verbreitete Calibri. Nun wird Calibri ausschliesslich von Microsoft für Microsoft-Umgebungen und –Applikationen vertrieben, ausser, man ist bereit, etwas dafür zu bezahlen. Wir haben versucht, den Calibri-Font vom Windows auf den Linux-Server zu kopieren – dies hat mit unserer Website sogar geklappt. Wir wollen ja aber natürlich nichts Illegales tun. Also haben wir nach einem freien Font gesucht, der in der Feinheit und der Schrittweite etwa unseren Vorstellungen (und natürlich unseren ästhetischen Erwartungen) entspricht. Google Fonts hat eine riesige Auswahl, trotzdem haben wir dort nichts Passendes gefunden. Aber nach weiteren Expeditionen sind wir auf Carlito gestossen, der etwa unserem Bedürfnis entsprach. Diesen Font kopierten wir in unser Child Theme, in das Unterverzeichnis fonts. Nun, da Microsoft-Produkte sehr verbreitet sind: Könnte man nicht veranlassen, dass überall dort Calibri angezeigt wird, wo es dem Browser bekannt ist? Und in den übrigen Fällen (Apple-Betriebssysteme, Android) unser Carlito? Dazu haben wir unsere eigene Schriftart ‚Calibri-Carlito‘ definiert und dazu im style.css unseres Child Theme folgenden Eintrag hinzugefügt:
@font-face { font-family: 'Calibri-Carlito';
             src: local('Calibri'), url('fonts/Carlito-Regular.ttf') format('truetype');
             font-display: swap; }
@font-face { font-family: 'Calibri-Carlito';
             src: local('Calibri Italic'), url('fonts/Carlito-Italic.ttf') format('truetype');
             font-style: italic;
             font-display: swap; }
@font-face { font-family: 'Calibri-Carlito';
             src: local('Calibri Bold'), url('fonts/Carlito-Bold.ttf') format('truetype');
             font-weight: bold;
             font-display: swap; }
@font-face { font-family: 'Calibri-Carlito';
             src: local('Calibri Bold Italic'), url('fonts/Carlito-BoldItalic.ttf') format('truetype');
             font-weight: bold;
             font-style: italic;
             font-display: swap; }
Nun wird im Browser (local) Calibri gesucht und verwendet und, wenn nicht vorhanden, vom Server (url) Carlito geladen, und das in den üblichen Schriftschnitten. Die Anweisung font-display: swap hat zur Folge, dass beim ersten Download des Fonts, der doch eine gewisse Zeit dauern kann, zuerst (nach einigen Sekundenbruchteilen Wartezeit) der Standard-Font des Browsers verwendet wird, der nach vollendetem Download durch Carlito ersetzt wird.

Schliesslich haben wir uns aber entschieden, vorläufig die von Elementor verwendete Schriftart Roboto zu übernehmen. Falls wir die Default-Typo verwendeten, erschiene bei den Microsoft-Usern in den meisten Fällen Arial. Dies wollten wir nicht, da uns vor allem die (von el favorisierten) Überschriften in VERSALIEN damit nicht gefallen.

Hier Kommentar schreiben