Mehrsprachigkeit bei PlugIns für WordPress

WordPress benötigt für jede weitere Sprache eine zusätzliche Sprachdatei. Die Grundsprache ist im Prinzip das, was der Entwickler im Code verbaut hat. Im besten Falle in Englisch. Aus dem Code generiert man eine Datei als Vorlage, aus der dann die Sprachdateien abgeleitet werden.

Die Struktur

In WordPress wird der Basisname eines Plugins Slug genannt. Der Name des Plugin-Verzeichnisses, bzw. der Name der Plugin-Datei gibt den Slug vor. Beide müssen identisch sein. Bitte keine Unterstriche verwenden.
/wordpress/wp-content/plugins/{slug}/{slug}.php
/wordpress/wp-content/plugins/my-plugin/my-plgin.php
Die Sprachdateien sind in einem Unterverzeichnis des Plugin-Verzeichnisses gespeichert. Standard bei WordPress ist languages.
/wordpress/wp-content/plugins/{slug}/languages/
/wordpress/wp-content/plugins/my-plugin/languages/
WordPress benötigt sogenannte “Maschine Object”-Dateien .mo für die Übersetzung. Das sind die eigentlichen Sprachdateien. Pro Sprache und Region wird eine Datei benötigt. Der Name einer Sprachdatei setzt sich aus dem Slug und der Länderkennung zusammen. Wie die .mo-Dateien erstellt werden erkläre ich später.
../languages/{slug}-{language}_{COUNTRY}.mo

../languages/my-plugin-de_DE.mo
../languages/my-plugin-en_US.mo
../languages/my-plugin-fr_FR.mo

Die PlugIn-Datei

Im Header der PlugIn-Datei kommt der Slug an sich nicht vor. Lediglich die Text-Domain muss eingetragen werden und so heissen wie der Slug. Aktuelle WordPress-Versionen machen das automatisch. Ebenso muss das Verzeichnis angegeben werden, das die Sprachdateien beinhaltet. Das macht Word-Press nur automatisch, wenn das PlugIn aus dem offiziellen WordPress-Pool kommt.
/*
 * Plugin Name: My Plugin
 * Author: Plugin Author
 * Text Domain: my-plugin
 * Domain Path: /languages
 */
Wir müssen WordPress noch auffordern, das die Sprachdateien auch geladen werden.
function my_plugin_load_languages() {
    load_plugin_textdomain( 'my-plugin', FALSE, basename( dirname( __FILE__ ) ) . '/languages/' );
}
add_action( 'plugins_loaded', 'my_plugin_load_languages' );

Textausgaben im Code

Alle sprachabhängigen Texte müssen über WordPress-Funktionen umgeleitet werden.
__() Zuweisungen von sprachabhängigen Texten (Code Referenz bei WordPress)
// This works, but it's not multilingual.
$message = 'Hello, World!';    

// This is how to assign translated text correctly.
$message = __( 'Hello, World!' , 'my-plugin' ); 
_e() Ausgabe von sprachabhängigen Texten (Code Referenz bei WordPress)
// This works and it's multilingual.
echo __( 'Hello, World!' , 'my_text_domain' );  

// But this is how to display translated text correctly.
_e( 'Hello, World!' , 'my-plugin' );

Hinweise für Übersetzer

Der Entwickler kann dem Übersetzer auch Hinweise für seinen im Quelltext benutzten Text mit auf den Weg geben. So hat der Übersetzer nicht nur Text-Fragmente zur Übersetzung zur Verfügung, sondern kann an den Gedanken des Entwicklers anknüpfen.
Vor den Funktionen __() und _e() einfach die Bemerkung /* TRANSLATORS: */ hinzufügen.
/* TRANSLATORS: Welcome text when user signed in */
_e( 'Welcome to our world!' , 'my-plugin' ); 
Richtig wichtig wird die Verwendung von Hinweisen bei printf() oder sprintf() mit eingebetteten Variablen. Nur so kann der Übersetzer diese Variablen sprachabhängig sinnvoll einsetzen.
// Display translated text with embedded Variable.
printf(
    /* TRANSLATORS: %s: Name of a person */
    __( 'My name is %s.', 'my-plugin' ),
    $name
);
Werden mehrere Variablen eingebettet, können diese einfach durchnummeriert werden.
// Display translated text with more than one embedded Variable.
printf(
    /* TRANSLATORS: %1$s: Name of a person %2$s: Name of a city */
    __( 'My name is %1$s and i am from %2$s.', 'my-plugin' ),
    $name,
    $city
);
So kann bei der Übersetzung auch die Reihenfolge sprachabhängig geändert werden.
// Display translated text with more than one embedded Variable in custom order.
printf(
    /* TRANSLATORS: %1$s: Name of a person %2$s: Name of a city */
    __( 'I am from %2$s and they call me %1$s.', 'my-plugin' ),
    $name,
    $city
);

Sprachdateien erstellen und veröffentlichen

Ein Spracheditor wird jetzt benötigt, um die im Code vorbereiteten sprachabhängigen Texte zu finden und anschließend die gewünschten Sprachdateien zu erstellen. Ich hab das in einem eigenen Beitrag beschrieben.
Die generierten .mo-Dateien müssen in das Sprachverzeichnis kopiert und umbenannt werden. Der Dateiname beginnt mit dem Slug, einem Bindestrich und der Länderkennung.
../languages/{slug}-{language}_{COUNTRY}.mo

../languages/my-plugin-de_DE.mo
../languages/my-plugin-en_US.mo
../languages/my-plugin-fr_FR.mo
Das war’s.