Texte in einem WordPress-Theme, die übersetzbar sein sollen, müssen in den Templates gekennzeichnet werden. Dar Code dazu sieht ein wenig ungewöhnlich aus und es gibt viele verschiedene Schreibweisen für diese Funktion. Ich hab eine Weile gebraucht, bis ich mir einen Reim drauf machen konnte.
Der Aufbau eines übersetzbaren Strings ist immer gleich:
__( 'Der zu übersetzende Text', 'text-domain' );
Am Anfang stehen zwei Unterstriche. Die Syntax __()
ist ein Kürzel für die translate()-Funktion und setzt das Signal „Achtung, hier gibt’s was zu übersetzen“. Danach kommt der zu übersetzende Textschnipsel, am Ende steht die Textdomain.
An der Stelle, wo die zwei Unterstriche platziert sind, können ganz unterschiedliche Funktionen stehen. Ich möchte vier Varianten vorstellen, die ich im meinem Theme-Alltag am Häufigsten verwende.
Es gibt natürlich noch viel mehr Funktionen. Eine vollständige Übersicht mit ausführlichen Code-Beispielen gibt es im WordPress Theme Handbook.
1. Einfacher Text
esc_html_e('Ich bin ein Text, sonst nix' , 'text-domain');
Damit kennzeichne ich einen einfachen Text.
Im Prinzip würde diese Schreibweise ausreichen:
_e('Ich bin ein Text, sonst nix' , 'text-domain');
Ich bin nicht sicher, wie hoch das Risiko tatsächlich ist, aber theoretisch könnte bei der zweiten Variante ein Übersetzer HTML-Codeschnipsel oder Übleres in die Übersetzung reinschmuggeln. Die Escape-Funktion schmeisst solche Sachen raus.
2. Text innerhalb eines Attributs
Ist ein Text Teil eines Attributs und sitzt z.B. im title-Attribut innerhalb eines Links, dann sieht das Ganze so aus:
esc_attr_e( 'Skip to content', 'text-domain' );
Auch hier ist das Escapen wichtig, damit niemand über die Übersetzung Schadcode einschleusen kann.
3. Texte gemischt mit Variablen
Sind Variablen im Spiel, z.B. Platzhalter wie %s
zusammen mit PHP-Variablen, kommt die PHP-Funktion printf zum Einsatz.
Hier wird eine Postleitzahl zusammen mit einem übersetzbaren Text ausgegeben:
printf(
__( 'Die Postleitzahl ist %s.', 'text-domain' ),
$plz
);
4. Texte, die in Einzahl und in Mehrzahl vorkommen
In WordPress-Themes tauchen Einzahl und Mehrzahl klassischerweise im Zusammenhang mit Kommentaren auf. Gibt es erst einen Kommentar, wird der Text „Ein Kommentar“ ausgegeben, gibt es mehrere Kommentare soll die Pluralform erscheinen.
Das sieht im Template dann so aus:
printf(
_n(
'Ein Kommentar',
'%s Kommentare',
get_comments_number(),
'text-domain'
),
number_format_i18n( get_comments_number() )
);
Hier nochmal der Hinweis auf das Kapitel Internationalization im WordPress Theme Handbook. Dort werden die hier vorgestellten und weitere Optionen ausführlich erklärt.
Kommentare
•
Zum Thema Sicherheit: In Attributen wie z.B. title sollte immer escaped werden, d.h. völlig richtig dass esc_attr_e() verwendet werden soll.
Bei normalen Text sind wir Theme Entwickler uns selber nicht einig ;)
Automattic und WordPress.com fordern in ihren Theme Richtlinien das Escapen jeder Übersetzung. Deshalb sind auch in Underscores alle Texte mit esc_html_e() und esc_html__() umschlossen.
Die WordPress.org Theme Richtlinien erfordern es nicht. Die Twenty* Core Themes setzen sogar explizit auf __() und _e(). Für die Gründe dieser Entscheidung lohnt sich dieses Core Ticket zu lesen: https://core.trac.wordpress.org/ticket/30724
Ich persönlich escape alle Texte, weil das Verwenden der sicheren Funktionen keinen Nachteil hat und ich dann Sprachdateien nicht genau auf unerwünschten Code überprüfen muss.
LG,
Thomas
•
Hallo, Thomas,
Danke für Deinen Kommentar!
Ich habe für mich auch beschlossen, alles zu escapen.
Ich habe eine Weile auf diesem Thread rumgekaut https://github.com/Automattic/_s/issues/231.
Dort wird ein Unterschied zwischen „normalen“ Texten und Strings mit HTML gemacht.
So ganz verstehe ich die Unterscheidung nicht. Im Prinzip kann ja über die Sprachdatei in jeden String etwas Gemeines eingeschleust werden, immer vorausgesetzt, der kriminelle Energie ist da.
Schöne Grüße
Kirsten
•
Hallo Kirsten,
Underscores nutzt Escaping für alle übersetzbaren Texte.
Die Unterscheidung in dem Thread ist eher technisch. Normale Texte werden mit esc_html_e() und esc_html__() escaped. Für Strings mit HTML Code klappt das aber nicht, weil durch das Escapen alle HTML Tags entfernt werden. Ein übersetzbarer Text mit Links oder span Tags würde dann nicht mehr funktionieren.
Deshalb werden in Underscores Texte mit HTML Code durch __() übersetzt, und anschließend mit wp_kses() auf Schadcode überprüft: https://codex.wordpress.org/Function_Reference/wp_kses
Der wp_kses() Funktion kann mit dem zweiten Parameter genau übergeben werden, welcher HTML Code erlaubt ist. Dadurch kann unterwünschtes HTML auch wieder verhindert werden.
Sieht dann in etwa so aus:
wp_kses( __( ‚Ein Text mit HTML Code‘, ‚text-domain‘ ), array( ’span‘ => array( ‚class‘ => array() ) ) );
Leider wird der Code damit etwas kompliziert und unleserlich.
LG,
Thomas