Ändern Sie die Sprache durch Klicken auf eine Schaltfläche


21

Das Ziel ist es, eine Schaltfläche / Auswahl-Dropdown-Liste oder Ähnliches anzubieten, um die Sprache der öffentlichen Benutzeroberfläche 1) im laufenden Betrieb umzuschalten .

Wonach ich suche

  • Plugin oder Theme Code ...
  • ... oder Ideen
  • Verwenden eines Workarounds mit load_textdomain() Umgehungslösung mit verwenden, wird empfohlen, die Übersetzung in PO / MO-Dateien zu hinterlassen
  • Ideen zum Parsen der Zeichenfolgen in die Benutzeroberfläche (z. B. Ajax- / Plain-PHP- / INI-, JSON-, XML-Dateien), wenn Sie sich nicht auf eine Textdomain-Funktion verlassen

Hinweis:

1) Es geht nicht darum, in verschiedenen Sprachen zu veröffentlichen.

2) Ich benötige keinen Code, um das eigentliche Dropdown / den eigentlichen Button / was auch immer zu erstellen. Es geht nur darum, dass der Code / das System die Zeichenfolgen für die Benutzeroberfläche bereitstellt.

Vielen Dank!


1
Wenn Sie sich mit einer Seitenaktualisierung zufrieden geben können, kann eine Neudefinition der WPLANGKonstante eine Option sein. Ich mache das auf zwei Websites mit mehrsprachigem Inhalt, bei denen das Mehrsprachigkeits-Plugin keine UI-Übersetzung auslöst. Wenn es eine AJAX / JSON-Lösung sein muss, würde ich nicht wissen, wie ich helfen kann.
Johannes Pille

@JohannesPille An welcher Stelle / an welchem ​​Haken wechseln Sie? Btw: Könnten Sie das auf eine Antwort verschieben. Schon eine Abstimmung wert. Vielen Dank.
Kaiser

Ich mache es in einem Plugin, keine Hooks beteiligt. Es ist eine ziemlich schmutzige Sache und ich bin nicht so stolz darauf, aber es hat zu der Zeit die Arbeit erledigt. Sie können den Code des Plugins in diesem Pastebin sehen . Was es tut, ist selbsterklärend. Die Seite, von der ich dies kopiert habe, verwendet die letzte kostenlose Version von WPML. Fair genug, bewegte es auf eine Antwort.
Johannes Pille

Die Pastebin-URL scheint tot zu sein.
PapaFreud

@JohannesPille Würde es Ihnen etwas ausmachen, Ihren Code als Update für Ihr Q zu veröffentlichen oder einen Pastebin hinzuzufügen, der nicht abläuft?
Kaiser

Antworten:


15

Mit Abstand der beste (einfachste) Weg ist die Verwendung des Gebietsschemafilters (innen) get_locale() ).

Richten Sie zunächst eine Schnellfunktion zum Abrufen einer anderen Sprache für den localeFilter ein.

/**
 * A function returns with returns the user's selectd locale, if stored. 
 */
function wpse35622_get_new_locale($locale=false){
$new_locale = get_user_meta(get_current_user_id(), 'wpse_locale', true);
    if($new_locale)
        return $new_locale;

    return $locale;
}

Ich habe dies als globale Funktion belassen, könnte praktisch sein ...? Den Rest des Plugins habe ich in einer Klasse verpackt.

Es wird ein Dropdown-Menü mit möglichen Sprachen erstellt, aus denen Sie auswählen können.

Nachteile

  • Sucht wp-content/languagesnach Dateien des Formularsxx_xx.mo . Wenn es nicht von dieser Form ist (nicht alle .mo-Dateien sind es), wird das Plug-in es nicht erkennen!
  • Die Dropdown-Liste enthält eine Liste der gefundenen Gebietsschemas zur Auswahl. Diese werden jedoch im Format "xx_xx" der Gebietsschemas angezeigt, nicht auf menschenfreundliche Weise. Irgendwelche Ideen?
  • Tut $localeetwas anderes als Sprache? In diesem Fall ist es immer noch möglich, dasselbe Gebietsschema zu erhalten, aber alternative Übersetzungen bereitzustellen. Es ist allerdings viel unordentlicher ...

Der Code

class SH_Pick_Lang{
    /**
     * A unique name for this plug-in
     */
    static $name ='sh_pick_lang';

    /**
     * Hook the functions
     */
    public function __construct(){

        if( isset($_POST[self::$name]) ){
            add_action('locale',array($this,'update_user'));
        }
        add_filter( 'locale', 'wpse35622_get_new_locale',20 );
        add_action( 'wp_before_admin_bar_render', array( $this, 'admin_bar') );
    }

    /**
     * Update the user's option just in time! Only once mind...
     */
    function update_user($locale){
        $save_locale = $_POST[self::$name];
        update_user_meta(get_current_user_id(), 'wpse_locale', $save_locale);
        remove_filter(current_filter(),__FUNCTION__);
        return $locale;
    }

    /**
     * Add a really horrible looking dropdown menu that I'm sure Kaiser will make look fantastic.
     */
    function admin_bar(){
        global $wp_admin_bar;

        $wp_admin_bar->add_menu( array(
            'id'        => 'shlangpick',
            'title'     => $this->wpse_language_dropown(),
        ) );
    }

    /**
     * Generates a list of available locales.
     * Searches the wp-content/languages folder for files of the form xx_xx.mo
     * 
     * TODO Not all locales are of the form xx_xx.mo - we might miss some.
     * TODO Better way of gettin gthe wp-content/languages folder without a constant?
     */
    function wpse_language_dropown(){
         $name = self::$name;
         $locale = get_locale();
         $langs = get_available_languages();
         $langs[] = 'en_US';

         //For the labels (format_code_lang)
         require_once( ABSPATH . 'wp-admin/includes/ms.php');

         $html = "<form method='post'> ";
         $html .= "<select name='{$name}'>";
         foreach($langs as $lang){
              $label = format_code_lang( $lang );
              $html .= "<option ".selected( $lang, $locale, false)." value='{$lang}'>{$label}</option>";
        }
         $html .= "</select>";
         $html .= get_submit_button('Change Language','secondary', 'submit', true);
         $html .= "</form >";

         return $html;
    }

} // END Class

//Initiate...
$sh_pick_lang = new SH_Pick_Lang();

1
Upvote gemacht (lacht auch über alle Inline-Kommentare). Das Kopfgeld ist festgesetzt und wird Ihnen so bald wie möglich gutgeschrieben.
Kaiser

2
Aktualisiert, um die Antwort auf diese Frage wiederzugeben .
Stephen Harris

Keiner. Mit Lesezeichen versehen. +1
Johannes Pille

Mir ist aufgefallen, dass nur das Einschließen 'wp-admin/includes/ms.php'eine Administratorbenachrichtigung zum Aktualisieren Ihrer Netzwerksites auslöst (wenn Sie eine einzelne Site sind!). Möglicherweise format_code_lang()muss dies in einer benutzerdefinierten Funktion dupliziert werden.
Stephen Harris

Ich habe ein Gist mit meiner Bereinigung hinzugefügt - hatte keine Zeit, es zu testen, da ich derzeit mit Plugin-Ordnern herumspiele und dies bedeutet, dass kein anderes Plugin funktioniert. Hoffe, Sie können mit dem bereitgestellten Kern und vielleicht Gabel / Update arbeiten. Ich kann das Kopfgeld in einer halben Stunde vergeben, muss aber jetzt gehen, also sende ich es morgen. Vielen Dank für all Ihre Arbeit - sollte in jeder Standardinstallation sein :)
Kaiser

5

Wenn Sie sich mit einer Seitenaktualisierung zufrieden geben können, kann eine Neudefinition der WPLANGKonstante eine Option sein. Ich mache das auf zwei Websites mit mehrsprachigem Inhalt, bei denen das Mehrsprachigkeits-Plugin keine UI-Übersetzung auslöst.


Hmm .. Sie könnten Ajax verwenden, um den Body oder das gesamte HTML-Tag der Seite zu ersetzen, nachdem Sie den obigen Code (in derselben Ajax-Anfrage) ausgeführt haben, auf Ihren Button geklickt haben oder so ähnlich.
Joshua Abenazer

+1. Hab mir nur deinen Pastebin angesehen. Das heißt, Ihr Setup ist http://example.com/language/whatever/richtig?
Kaiser

@kaiser Yup, das ist das Setup auf der Site, von der der Code stammt. Wenn Sie sich nur für die Sprache der Benutzeroberfläche interessieren, sollten Sie eine URL- Abfragezeichenfolge übergeben oder eine $_SESSIONVariable WPLANGfestlegen , die die Neudefinition beim nächsten Laden auslöst. Wenn Sie dies auf einer mehrsprachigen Site replizieren möchten, beachten Sie, dass der darin enthaltene Code, wie im Kommentar zum Pastebin angegeben, mit WPML (letzte kostenlose Version) funktioniert. Sie kann mit qTranslate nicht 1 zu 1 repliziert werden, da diese URIs nicht physisch sind, sondern über das mod_rewriteApache-Modul neu geschrieben werden. Ich bin sicher, dass es angepasst werden kann, aber nicht so funktioniert, wie es ist.
Johannes Pille

Ich werde qTranslate oder WPML nicht verwenden. Es geht wirklich nur um die Sprache der Benutzeroberfläche. Ad $_SESSION) Mein Problem ist, dass sie ziemlich schwierig zu handhaben sind und Dinge zwischen Globals und dem Array leicht verwechselt werden können. Wenn ich also versuchen möchte, einen Weg zur Veränderung zu finden WPLANG, muss ich einen soliden Weg finden, um ihn von einer Anfrage zur nächsten zu geben. Vielleicht add_query_arg/get_query_varwird der Trick ...
Kaiser

Ich habe gerade noch einmal darüber nachgedacht (die Lösung ist immer noch nicht in das Projekt integriert): Könnten Sie das in etwas Ajax verpacken? Ich denke, das wäre der beste Weg, um das zu umgehen. Ich möchte das Q schließen und als Lösung markieren :) Danke.
Kaiser

2

http://www.qianqin.de/qtranslate/

ist was du brauchst ...

Bearbeite ich - nach Kommentar. Erstens - danke für alle, die zum Downvotes-Strom beigetragen haben. (das ist was passiert wenn man nicht oft genug besucht: -))

now - Die Funktion, die den Schalter handhabt, befindet sich in qtranslate-core. (Beginnt mehr oder weniger in Zeile 80 - hängt von der gewünschten Version ab.)

Da Sie sich keinen NOT OOP-Code ansehen können und ich jetzt nichts anderes zu tun habe, habe ich 10 Minuten gebraucht, um diesen Non-OOP-Code mit einem weiteren Non-OOP-Code zu paraphrasieren.

(Entschuldigung - primitive alte Schule hier)

Angenommen, ich habe die Frage verstanden && Angenommen, Sie möchten, dass der Code für den Administrator bestimmt ist && Angenommen, Sie wissen, wie er auf das Front-End portiert wird, wenn Sie möchten && Angenommen, Sie verstehen, dass der Code nicht optimal ist:

<?php
/*
Plugin Name: k99 language switcher
Plugin URI: http://www.krembo99.com
Description: Admin Language switcher proof of concept only - do not use in production.
Version: 0.0.0.0.0.0.0.1
Author: Krembo99
Author URI: http://www.krembo99.com
*/ 
?>
<?php function k99_add_language_menu() {
    //  k99_load_ajax_display_functions();
?>  
    <div class="mgmb_help_setting">
    <?php _e('Language:','your_text_domain'); ?>
    <select name="mgmb_language_setting_help" id="mgmb_language_setting_help" onChange="mgmb_set_language_cookies(this.value);" >
        <option value="en_US" <?php if($_COOKIE['k99_userLang']=="en_US"){echo "selected";} ?>><?php _e('English','your_text_domain');?></option>
        <option value="de_DE" <?php if($_COOKIE['k99_userLang']=="de_DE"){echo "selected";} ?>><?php _e('German','your_text_domain');?></option>
        <option value="zh_CN" <?php if($_COOKIE['k99_userLang']=="zh_CN"){echo "selected";} ?>><?php _e('Chinese','your_text_domain');?></option>
    </select>
    </div>
<?php   
}
// Now we set that function up to execute when the help action is called
add_filter('contextual_help', 'k99_add_language_menu');

// I guess this is your mysterious "browser stuff"
function k99_language_change($lang){ 
 global $locale;
 // wp_cache_set( "language", $lang, 'options' );
    if ( isset($_COOKIE['k99_userLang'])) {
      $lang = $_COOKIE['k99_userLang'];
    }
    define( 'WPLANG', $lang );
 if($locale!= $lang) {
    $locale = $lang;
    load_plugin_textdomain('your_text_domain', false, dirname( plugin_basename(__FILE__) ) . '/lang'); // sample use for plugins textdomain
    load_plugin_textdomain('your_text_domain2', false, dirname( plugin_basename(__FILE__) ) . '/lang');
    load_plugin_textdomain('your_text_domain3', false, dirname( plugin_basename(__FILE__) ) . '/lang');
 }
  return $locale;
}
add_filter('locale', 'k99_language_change',99);

////////// +++++++++++++++  START COOKIES CREATION +++++++++++++++//////////////////
// Javascript function set the language cookies
// access external
// @param lang - language code
// @return NULL
// or maybe this is the OP´s mysterious "browser stuff" ??
    function mgmb_print_script() {
    ?>
    <script type="text/javascript" >
    function mgmb_set_language_cookies(lang){   
        var Then = new Date(); 
        Then.setTime(Then.getTime() + 10000*60*60*1000 ); //set cookie expire to 10000 hours cookies (hour*minute*seconds*1000)
        document.cookie = "k99_userLang="+lang+";expires="+ Then.toGMTString();
        window.location.reload();
        } 
        </script>
<?php
} 
add_action('admin_print_scripts', 'mgmb_print_script');  // this is not the right way to do .. but no time now.
?>

BEMERKUNGEN :

1 - Dies wurde in 10 min gebaut. auf der lokalen Maschine am Flughafen. Der Grund, warum ich das sage, ist, dass die einzige fertige WordPress-Installation, die ich hier habe, ziemlich alt ist. (2,9 denke ich).

Dies bedeutet, dass wahrscheinlich das Sprachmenü UNTER der kontextbezogenen Hilfediv angezeigt wird, da kürzlich eine neue Div-Struktur (mit Registerkarten) eingeführt wurde - sie sollte aber dennoch funktionieren. (Ich verspreche, später darauf zurückzukommen, wenn ich Zeit habe.)

Wenn ich mehr Zeit hätte (und einen neuen WordPress-Code hier), würde ich dies wahrscheinlich in die neue Admin-Leiste mit integrieren add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 );(ich habe bereits versprochen, darauf zurückzukommen).

2 - Sie sollten die aufgelisteten Sprachdateien im Ordner "languages" in wp-content (besser ??) oder wp-include haben. in diesem Punkt - der Code ist nur ein Proof-of-Concept - und wenn man mehr Zeit hat, sollte das Menü natürlich dynamisch aufgebaut sein und nicht wie hier gemacht.

3 - Ihr WPLANG in der Konfiguration sollte leer sein. Ich bin nicht sicher, ob es auf neueren WP-Versionen funktioniert, wenn bereits eine Sprache eingestellt ist.

4 - Es handelt sich um einen einfachen synthetisierten und umschriebenen Proof of Concept, der auf dem basiert, was im qtranslate-Code (auch in der alten Version) zu sehen war. Die meisten Dinge werden also "schnell" und nicht unbedingt "richtig" ausgeführt (wie das Hinzufügen von JS) , keine dedizierte Textdomain etc ..).

EDIT II

Jemand hat heute Glück! (Flugverspätung )

Da Sie nach "Ideen" für Ansätze gesucht haben, ist hier eine andere berühmte.

Es passt nicht in ein Plugin oder eine andere nicht-exklusive Umgebung, aber es kann Ihnen eine andere Richtung geben, wie Sie mit dem "Browser-Zeug" umgehen sollen.

Dies ermöglicht es einem, die Sprache mit einem GET wie: <a href="index.php?lang=de">German</a>oder zu erhalten<a href="whatever.php?lang=ml">my Language</a>

Zur Verwendung können Sie einen Code erstellen (nennen wir ihn wp-langswitch.php)

 session_start();
 if ( isset( $_GET['lang'] ) ) {
    $_SESSION['WPLANG'] = $_GET['lang'];
    define ('WPLANG', $_SESSION[WPLANG]);
 } else {
    if(isset($_SESSION['WPLANG'])) {
        define ('WPLANG', $_SESSION['WPLANG']);
        $_GET['lang'] = $_SESSION['WPLANG'];
    } else {
        if ( isset( $_SERVER["HTTP_ACCEPT_LANGUAGE"] ) ) {
            $languages = strtolower( $_SERVER["HTTP_ACCEPT_LANGUAGE"] );
             $languages = explode( ",", $languages );
            $_SESSION['WPLANG'] = $languages[0];
            $_SESSION['WPLANG'] = str_replace("-", "_", $_SESSION['WPLANG']);
            $_GET['lang'] = substr($_SESSION['WPLANG'],0,2);
            define ('WPLANG', $_SESSION[WPLANG]);
        } else {
            define ('WPLANG', '');
        }
    }
 }

Jetzt müssen wir in wp-config kurz vor der WPLANG-Konstante unseren Code einfügen.

 require_once(dirname(__FILE__).'/wp-langswitch.php');
 define ('WPLANG', ''); 

Jetzt - natürlich ist es besser, der Mischung einige Cookies hinzuzufügen, um die Sprachen zu speichern.

EDIT III

Ich habe versprochen, später darauf zurückzukommen - hier ist, wie es (auf eine sehr unkorrekte und primitive Weise) in die Admin-Leiste integriert werden kann (anstelle des Kontext-Hilfemenüs)

 function k99_add_language_menu_bar() {
    global $wp_admin_bar, $wpdb;
    if ( !is_super_admin() || !is_admin_bar_showing() )
        return;
// I am sure you can find a way alone to construct array from reading folder . If not , comment and I will update again.

if($_COOKIE['k99_userLang']=="en_US"){$sel==$_COOKIE['k99_userLang'];} 
if($_COOKIE['k99_userLang']=="de_DE"){$sel==$_COOKIE['k99_userLang'];}
if($_COOKIE['k99_userLang']=="zh_CN"){$sel==$_COOKIE['k99_userLang'];}

    $k99_lang = '';
    $k99_lang .= '<select name="mgmb_language_setting_help" id="mgmb_language_setting_help" onChange="mgmb_set_language_cookies(this.value);" >';
    $k99_lang .= '<option value="en_US" >English</option>';
    $k99_lang .= '<option value="de_DE" >German</option>';
    $k99_lang .= '<option value="zh_CN" >Chinese</option></select>';

    /* Add the main siteadmin menu item */
    $wp_admin_bar->add_menu( array( 'id' => 'Language', 'title' => __( 'language', 'your_text_domain3' ), 'href' => FALSE ) );
    $wp_admin_bar->add_menu( array( 'parent' => 'Language', 'title' => $k99_lang, 'href' => FALSE ) );
}
add_action( 'admin_bar_menu', 'k99_add_language_menu_bar', 999 );

Ersetzen Sie einfach diese Funktion (oder fügen Sie sie dem alten Code hinzu) (das ursprüngliche NICHT-OOP-Nicht-Plugin).

Wie gesagt, ich habe hier auf local keine neue WordPress-Installation mit Admin-Leiste - aber es sollte funktionieren.

(und dann könnte es auch nicht funktionieren ... aber ich bin sicher, dass Sie das beheben können, wenn Sie es wirklich wollen - auch wenn Sie dachten, dass es kein OOP ist) :-)

muss jetzt rennen hoffe es hilft irgendwie.

EDIT IV - Edit III wurde in die Arbeitsversion für die Admin-Menüleiste geändert (zumindest auf meinem WP 3.4)

da ich keine funktionierende Installation von 3.4 hatte - und jetzt zurückkehre und ich tue - habe ich die Edit III-Lösung bearbeitet - und es funktioniert für mich.

Über die Upvotes konnte ich mich nicht weniger Gedanken machen. Und ich brauche keine "Kopfgelder" (was auch immer das sein mag ...). Es war nur zum Zweck der Übung, die Sie vielleicht dem Autor von qTranslate geben sollten. :-) trotz der Tatsache, dass es nicht OOP ist - es ist ein geniales Plugin, von dem man in vielen Bereichen viel lernen kann. Wenn man bedenkt, wann dieses Plugin veröffentlicht wurde, ist es sogar erstaunlich. die unbeschreibliche Mühe wert, einen NON OOP-Code zu lesen - auch wenn es nicht so ist - OOP. Und selbst wenn es nicht richtig eingerückt ist (guter Gott!).


3
Vielleicht steckt eine Lösung in der Tiefe dieses Codes, aber es ist nahezu unmöglich, alle Wege herauszufinden, da es nicht in OOP geschrieben ist. Wenn Sie wissen, wo genau sich die Spracherkennung befindet (im Browser) und wie sie die Gettext-Zeichenfolgen filtert, lassen Sie es mich bitte wissen.
Kaiser

1
@kaiser - siehe edit ich für "browser stuff".
krembo99

1
@kaiser ..und siehe edit II für weitere "Browser-Informationen" - und edit III für die Integration der "Browser-Informationen" in die "Browser-Informationen".
krembo99

Ok, ich habe es für deine Mühe empfohlen (nicht um hier zurückzukehren). Die Idee mit einem Cookie ist schön. Wie auch immer, hier sind ein paar Hinweise: Edit II wird nach dem einen Fehler auslösen require(). Sie können nicht define()zweimal dieselbe Zeichenfolge verwenden. Edit III hat einige Probleme mit den Sprachen. Die Auswahl en_USwürde nichts bewirken (?), Aber de_DEauf English;) setzen. Um es zusammenzufassen: Ich vergebe Kopfgelder und verteile sie an (zum Beispiel StephenHarris) für eine vollständige und funktionierende Antwort. Wenn Sie so etwas haben, aktualisieren Sie bitte Ihre Antwort (Cookie-Ansatz interessant) und ich kann hinzufügen und belohnen Sie ein Kopfgeld.
Kaiser

Bitte hinterlasse keine Kommentare für mich. Nehmen Sie Änderungen an Ihrer Antwort vor, damit jeder Ihre Ideen lesen kann. Anmerkung: imho externer Code sollte immer als Plugin / MU-Plugin / Theme / DropIn hinzugefügt werden, damit er verschiebbar ist.
Kaiser
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.