web-dev-qa-db-fra.com

Changer de langue en cliquant sur un bouton

L’objectif est d’offrir un bouton/sélection déroulant ou similaire pour changer l’interface publique1) langue à la volée.

Ce que je cherche

  • Plugin ou Code Thème ...
  • ... ou Idées
  • Utiliser une solution de contournement avec load_textdomain() serait apprécié de laisser la traduction aux fichiers .po/.mo
  • Idées sur la façon d'analyser les chaînes dans l'interface (par exemple, ajax/plain php/ini, fichiers json, xml) sans recourir à une fonction textdomain

Remarque:

1) Il ne s'agit pas de publier dans différentes langues.

2) Je n'ai pas besoin de code pour créer le menu déroulant/le bouton/peu importe. Il ne s'agit que du code/système fournissant les chaînes pour l'interface utilisateur.

Merci!

21
kaiser

De loin, le meilleur moyen (le plus simple) consiste à utiliser le filtre de paramètres régionaux (à l'intérieur de get_locale() ).

Commencez par configurer une fonction permettant de récupérer une langue différente à utiliser sur le filtre locale.

/**
 * 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;
}

J'ai laissé cela comme une fonction globale, pourrait être utile ...? Le reste du plug-in que j'ai enveloppé dans une classe.

Il crée une liste déroulante de langues possibles parmi lesquelles vous pouvez sélectionner.

Désavantages

  • Recherche wp-content/languages pour les fichiers de la forme xx_xx.mo. Si ce n'est pas le cas (tous les fichiers .mo ne le sont pas), le plug-in ne le détectera pas!
  • Le menu déroulant fournit une liste des paramètres régionaux trouvés parmi lesquels choisir, mais ceux-ci sont affichés dans le format "xx_xx" des paramètres régionaux, et non de manière conviviale - aucune idée?
  • Est-ce que $locale fait autre chose que la langue? Si tel est le cas, il est toujours possible d’obtenir les mêmes paramètres régionaux, mais en fournissant des traductions alternatives. C'est beaucoup plus sale cependant ...

Le 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();
15
Stephen Harris

Si vous pouvez vous contenter d'actualiser une page, redéfinir la constante WPLANG pourrait être une option. Je le fais sur deux sites à contenu multilingue où le plug-in multilinguisme ne parvient pas à déclencher la traduction de l'interface utilisateur.

5
Johannes Pille

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

est ce qu'il vous faut ...

Edit I - après le commentaire. Tout d’abord, merci à tous ceux qui ont contribué au downvotes torrent. (c'est ce qui arrive quand on ne visite pas assez souvent: -))

now - La fonction qui gère le commutateur est dans qtranslate-core. (commence à la ligne 80 plus ou moins - dépend de la version que vous voulez.)

Puisque vous ne pouvez pas regarder dans un code NOT OOP, et que je n’ai maintenant plus rien à faire - j’ai pris 10 minutes pour synthétiser, paraphraser la compilation de ce non-OOp avec encore un autre code non-OOP pour vous.

(désolé, - vieille école primitive ici)

En supposant que j'ai compris la question && En supposant que vous souhaitiez que le code soit destiné à admin &&, en sachant que vous saurez comment le porter au début du processus si vous souhaitez && en supposant que vous compreniez que le code n'est pas optimal:

<?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.
?>

REMARQUES :

1 - Cela a été construit en 10 min. sur une machine locale pendant votre séjour à l'aéroport. La raison pour laquelle je dis cela est que la seule installation WordPress disponible que je possède ici est assez ancienne. (2,9 je pense).

Cela signifie que le menu de langue apparaîtra SOUS la div div de l'aide contextuelle, car une nouvelle structure de div a été récemment introduite (avec des onglets) - mais cela devrait quand même fonctionner. (Je promets d'y revenir plus tard si j'en ai le temps)

Si j'avais plus de temps (et un nouveau code wordpress ici), j'intégrerais probablement cela dans le nouvel admin-bar avec add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 ); (j'avais déjà promis d'y revenir)

2 - vous devriez avoir les fichiers de langues listés dans le dossier "languages" dans wp-content (meilleur ??) ou wp-include. en ce qui concerne ce point - le code n’est qu’une preuve de concept - et, bien sûr, si le temps nous le permettait, le menu devrait être construit de manière dynamique et non comme ici.

3 - votre WPLANG dans la configuration doit être vide. Je ne suis pas sûr que cela fonctionnera avec les nouvelles versions de wp si une langue est déjà définie.

4 - c’est une simple démonstration de concept synthétisée et paraphrasée construite sur ce qui a été vu dans le code qtranslate (aussi ancienne version) - ainsi la plupart des choses se font de manière "rapide", pas nécessairement de la "bonne" manière (comme l’ajout de JS). , pas de textdomain dédié, etc.).

EDIT II

quelqu'un a de la chance aujourd'hui! (Retard de vol)

Puisque vous cherchiez des "idées" pour des approches, voici une autre célèbre.

Cela ne s'intégrera pas dans un plugin, ni dans aucun autre environnement non exclusif, mais cela pourrait vous donner une autre direction quant à la façon de gérer les "éléments du navigateur".

Cela permettra d’obtenir la langue avec un GET comme: <a href="index.php?lang=de">German</a> ou <a href="whatever.php?lang=ml">my Language</a>

Pour l'utiliser, vous pouvez créer un code (appelons-le 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', '');
        }
    }
 }

maintenant, dans wp-config, juste avant la constante de WPLANG, nous devons inclure notre code.

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

Maintenant - évidemment, il serait préférable d’ajouter des cookies au mixage pour stocker les langues.

EDIT III

J'ai promis d'y revenir plus tard - voici comment (d'une manière très erronée et primitive) il pourrait être intégré dans la barre d'administration (au lieu du menu d'aide contextuelle)

 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 );

Il suffit de remplacer cette fonction (ou d’ajouter) à l’ancien code (l’ancien NON - OOP non-plugin).

Comme je l'ai dit, je n'ai pas de nouvelle installation wordpress ici sur locale qui comporte admin-bar - mais cela devrait fonctionner.

(et puis encore, ça pourrait ne pas marcher ... mais je suis sûr que vous pourriez résoudre ce problème si vous le voulez vraiment - même si ce n'est pas OOP) :-)

je dois courir maintenant. espérons que cela aide d'une certaine manière.

EDIT IV - a modifié edit III en version de travail pour la barre de menus d'administration (au moins sur mon wp 3.4)

depuis que je n'avais aucune installation de travail de 3.4 - et maintenant je suis rentré et je fais - j'ai édité la solution Edit III - et cela fonctionne pour moi.

À propos des votes positifs, je m'en moque. Et je n’ai besoin d’aucune "prime" (quelles qu’elles soient…). C’est juste pour le plaisir de l’exercice que vous devriez peut-être le donner à l’auteur de qTranslate. :-) malgré le fait que ce n’est pas OOP - c’est un plugin génial avec beaucoup à apprendre dans beaucoup de domaines. compte tenu du "quand" de cette version du plugin, il est même étonnant. Cela vaut l'effort indescriptible de lire un code NON OOP - même s'il ne l'est pas - OOP. Et même si ce n'est pas correctement mis en retrait (bon dieu!).

2
krembo99