web-dev-qa-db-de.com

__ (): Was ist, wenn ich eine Variable übergeben muss?

In den Dokumenten für die Übersetzungsfunktion __( $text, $domain ) heißt es, dass Sie die Zeichenfolge direkt an die Stelle von $ text setzen müssen, damit Sie nicht etwas Schlaues wie __( $my_text, 'text-domain' ); tun können.

Ich schreibe jedoch eine Methode, die einen String aufnimmt und ihn irgendwie an __( ... ) übergeben muss. Gibt es einen Weg, z.B. über printf oder sprintf, dass ich das umgehen kann?

So etwas wie...

function print_description( $text ) {
    echo '<p>' . __( printf( '%s', $text ), 'text-domain' ) . '</p>';
}
3
geoff

Du kannst es mit printf() machen.

Z.B.

printf( __( 'We deleted %d spam messages.', 'my-text-domain' ), $count );
8
Ahmad Awais

Nein

Die Tools, die beim Generieren einer Übersetzung helfen, können Ihren Code nicht analysieren und entscheiden, welche Zeichenfolgen übersetzt werden müssen, wenn die an die Übersetzungsroutinen übergebenen Zeichenfolgen vollständig dynamisch sind.

in Ihrem Beispiel ist der richtige Weg, diese Funktion zu codieren

function print_description( $text ) {
    echo '<p>' . $text . '</p>';
}

und nenne es

print_description(__('specific description','text_domain));
3
Mark Kaplun

Nein, weil man keinen Text übersetzen kann, wenn man diesen Text nicht wirklich kennt.

Die Übersetzung erfolgt im Wesentlichen über ein großes Array. Sie nehmen Ihren Code, finden alle darin enthaltenen Zeichenfolgen und erstellen dann eine große Liste von Zeichenfolgen. Ein Übersetzer übersetzt sie in eine andere Sprache. Dann führen die verschiedenen Übersetzungsfunktionen eine große Array-Suche durch und geben den übersetzten String zurück.

Wenn Sie eine Variable verwenden, um die Textzeichenfolge zu speichern, besteht keine Möglichkeit, diese im Voraus zu ermitteln und in die anfängliche Liste der zu übersetzenden Zeichenfolgen aufzunehmen.

Variablen können in Übersetzungsfunktionen nicht verwendet werden, da dies eigentlich keinen Sinn ergibt. Sie können keine Variable übersetzen.

2
Otto

Um eine Zeichenfolge in WordPress zu übersetzen, müssen Sie wie in den meisten CMSs, die PHP verwenden, die Zeichenfolge in eine GetText-Übersetzungsfunktion einschließen (d. H. __ (), _e (), _n (), _x () ... usw.).

Die Zeichenfolge muss auch in einer PO-Datei enthalten sein (GetText Portable Object-Dateien, der Industriestandard für mehrsprachige Websites in PHP - https://www.gnu.org/software/gettext/manual/ html_node/PO-Files.html ). Diese Datei enthält Paare von Zeichenfolgen, von denen eine die Zeichenfolge in der Originalsprache und die andere die Übersetzung in der Zielsprache ist.

Um diese PO-Dateien für jede Sprache zu erstellen (zB my-text-domain-es_ES.po für Spanisch, my-text-domain-fr_FR.po für Französisch ... usw.), in die wir das Plugin oder übersetzen müssen Der Übersetzer verwendet eine POT-Datei (PO-Vorlage), die alle zu übersetzenden Zeichenfolgen in der Originalsprache enthält, und fügt für jede eine übersetzte Zeichenfolge hinzu. PO-Dateien werden zu binären MO-Dateien kompiliert, die viel schneller verarbeitet werden können.

Zur Laufzeit werden die zu übersetzenden Zeichenfolgen durch die MO-Dateien abgerufen und durch ihre Übersetzung ersetzt.

Die POT-Dateien werden normalerweise mit speziellen Tools generiert, die die Quellcodedateien analysieren und die übersetzbaren Zeichenfolgen extrahieren.

Wenn wir Code wie folgt schreiben:

    $translated_text = __( $text, 'my_text_domain');

Wenn der Code von den Spezialwerkzeugen analysiert wird, ist der Wert der zu übersetzenden Zeichenfolge ($ text) noch nicht definiert und daher im Code nicht vorhanden. Infolgedessen enthalten die automatischen Suchwerkzeuge diese Zeichenfolge nicht in der POT-Datei und sind daher weder in PO- noch in MO-Dateien enthalten.

Zur Laufzeit, wenn der Wert des Strings $ text vermutlich bereits definiert ist, gibt es für diesen Wert keine Entsprechung in den Übersetzungsdateien und die Übersetzung ist nicht möglich.

Wenn jedoch die Menge der möglichen Werte für diese Variable begrenzt ist und wir sie kennen, haben wir zwei Möglichkeiten, um dieses Problem zu lösen:

Option 1: Bearbeiten Sie die POT-Datei manuell, um die Einträge mit den möglichen Werten von $ text hinzuzufügen. Diese Option ist einfach und leicht zu implementieren. Jeder Code-Editor und minimale Kenntnisse des POT-Formats werden ausreichen. Aber es hat einen Nachteil. Jedes Mal, wenn wir die automatischen Suchwerkzeuge verwenden, um die Übersetzungen nach der Änderung unseres Codes zu aktualisieren, gehen die vorgenommenen Änderungen verloren und müssen manuell erneut eingefügt werden.

Option 2: füge in unseren Code alle möglichen Werte von $ text ein, die von Übersetzungsfunktionen umbrochen werden. Schauen wir uns ein Beispiel an. Angenommen, $ text kann die folgenden Werte annehmen: Apfel, Orange, Banane, Pfirsich und Birne. Wir müssten den folgenden Code schreiben:

    // this variable is used only to include as parameters in
    // translation functions all the possible values of $text 
    $locale = __('Apple', 'my_text_domain') .
              __('orange', 'my_text_domain') .
              __('banana', 'my_text_domain') .
              __('Peach', 'my_text_domain') .
              __('pear', 'my_text_domain');

    $translated_text = __( $text, 'my_text_domain');

Diese Option ist auch einfach zu implementieren und hat den Vorteil, dass sie nicht verloren geht, wenn wir die automatischen Suchwerkzeuge zum Aktualisieren der Übersetzungen verwenden.

Wenn wir in unserem Theme oder Plugin mehrere Variablen haben, die übersetzt werden sollen, und diese einen begrenzten Satz bekannter möglicher Werte haben, können wir alle in eine separate Datei aufnehmen, die sich im Stammordner oder in einem Unterordner befinden muss (dh "Includes" oder "Assets" -Ordner) des Themas oder Plugins, wie unten gezeigt:

    <?php
    //values of the variables to be translated
    $locale_var1 = __('text-of-var1_val1', 'my_text_domain') .
                   __('text-of-var1_val2', 'my_text_domain') .
                   __('text-of-var1_val3', 'my_text_domain') .
                   .......
                   __('text-of-var1_valn', 'my_text_domain');

    $locale_var2 = __('text-of-var2_val1', 'my_text_domain') .
                   __('text-of-var2_val2', 'my_text_domain') .
                   .......
                   __('text-of-var2_valn', 'my_text_domain');

    .............

    $locale_varn = __('text-of-varn_val1', 'my_text_domain') .
                   __('text-of-varn_val2', 'my_text_domain') .
                   .......
                   __('text-of-varn_valn', 'my_text_domain');

Dies ist ein sauberer und wartbarer Ansatz, bei dem die Definition dieser Zeichenfolgen in einer separaten Datei gespeichert wird, die geändert werden kann, ohne dass sich dies auf andere Codedateien auswirkt.

0
Juan Guerrero

Aus irgendeinem Grund funktioniert es für mich, Variablen an _e () zu übergeben:

$string = 'ciao';
_e($string, 'textdomain'); // put your own textdomain..
// will output 'ciao' or 'hello', based on current language

Natürlich müssen Sie Ihre Textdomain vorher erstellen, idealerweise in yourtheme/functions.php:

add_action( 'after_setup_theme', 'theme_setup' );
function theme_setup() {
  load_theme_textdomain( 'yourtextdomain', TEMPLATEPATH . '/languages' );
  // [...] other init code
}

Wenn ich das Wort 'ciao' in der .po-Datei übersetze, wird es im Frontend korrekt übersetzt. Verwenden Sie Poedit oder ähnliches, um die .mo zu kompilieren. Sowohl .po als auch .mo müssen in/wp-content/yourtheme/languages ​​abgelegt werden (entsprechend dem obigen Code).

#. Test en_EN.po
msgid "ciao"
msgstr "hello"

Ich bin mir nicht sicher, warum es funktioniert, aber es wird "ciao" auf italienisch und "hallo" auf englisch ausgeben.

0
Luca Reghellin

Wie ich hier erwähne http://www.westofwonder.com/2013/12/whats-with-all-the-double-underscores-everywhere/ (bitte entschuldigen Sie das Thema, ich habe Verbesserungen vorgenommen, nur Zuflucht noch nicht gepusht), eine mögliche Lösung besteht darin, eine Funktion für den Text zu erstellen:

function yourtheme_thisisthetext() {
    return __( 'This is the text.', 'yourthemetextdomain' );
}

An und für sich hässlich, aber für einen langen oder häufig verwendeten Übersetzungsstring kann sich der Kompromiss für die Lesbarkeit des Codes lohnen.

(Ist das erlaubt? Um in direkter Antwort auf eine Frage auf meinen Blog zu verlinken? Wenn nicht, entschuldige ich mich und werde es nicht noch einmal tun.)

0
LindaJeanne