Cambiar idioma haciendo clic en un botón

20

El objetivo es ofrecer un botón / selección desplegable o similar para cambiar el idioma de interfaz pública 1) sobre la marcha.

Lo que estoy buscando

  • Código de tema o del complemento ...
  • ... o Ideas
  • Se agradecería utilizar una solución alternativa con load_textdomain() para dejar la traducción a los archivos .po / .mo
  • Ideas sobre cómo analizar las cadenas en la interfaz (por ejemplo, ajax / plain php / ini, json, xml files) cuando no se confía en alguna función de dominio de texto

Nota:

1) No se trata de publicar en diferentes idiomas.

2) No necesito código para hacer el menú desplegable / botón / lo que sea real. Solo se trata del código / sistema que entrega las cadenas para la interfaz de usuario.

¡Gracias!

    
pregunta kaiser 05.12.2011 - 19:53

3 respuestas

15

De lejos, la mejor manera (la más fácil) es usar el filtro de configuración regional (dentro de get_locale() ).

Primero configure una función rápida para recuperar un idioma diferente para usar en el filtro 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;
}

He dejado esto como una función global, podría ser útil ...? El resto del complemento que he envuelto dentro de una clase.

Crea un menú desplegable de posibles idiomas entre los que puedes seleccionar.

Inconvenientes

  • Busca en wp-content/languages archivos del formulario xx_xx.mo . ¡Si no es de esa forma (no todos los archivos .mo lo son), el complemento no lo detectará!
  • El menú desplegable proporciona una lista de las configuraciones regionales encontradas para elegir, pero éstas se muestran en el formato 'xx_xx' de las configuraciones regionales, no es una forma amigable con el ser humano, ¿alguna idea?
  • ¿ $locale hace algo que no sea el idioma? Si es así, todavía es posible obtener la misma configuración regional, pero proporcionar traducciones alternativas. Aunque es mucho más complicado ...

El código

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();
    
respondido por el Stephen Harris 05.07.2012 - 15:21
5

Si puede conformarse con una actualización de la página, redefinir la constante WPLANG podría ser una opción. Lo estoy haciendo en dos sitios con contenido multilingüe donde el complemento de calidad múltiple no puede activar la traducción de la interfaz de usuario.

    
respondido por el Johannes Pille 05.12.2011 - 20:23
2

enlace

es lo que necesitas ...

Editar I - después del comentario. Primero, gracias a todos los que contribuyeron en el torrente downvotes. (esto es lo que sucede cuando uno no visita con la frecuencia suficiente: -))

ahora - La función que maneja el interruptor está en qtranslate-core. (comienza en la línea 80 más o menos, depende de la versión que desee).

Ya que no puedes mirar un código NOT OOP, y ahora no tengo nada más que hacer, me tomó 10 minutos sintetizar, parafraseo compilar ese non-OOp con otro código que no sea OOP para ti.

(lo siento, - antiguo skool primitivo aquí)

Suponiendo que entendí la pregunta & & Suponiendo que desea que el código sea para admin & & asumiendo que sabrá cómo portarlo al front-end si desea & & Suponiendo que entienda que el código no es óptimo:

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

OBSERVACIONES:

1 - Esto fue construido en 10 min. en la máquina local, mientras que en el aeropuerto. La razón por la que digo esto es que la única instalación de wordpress disponible que tengo aquí es bastante antigua. (2.9 creo).

Esto significa que probablemente el menú de idioma aparecerá BAJO el div de ayuda contextual, debido al hecho de que recientemente se introdujo una nueva estructura de div (con pestañas), pero aún así debería funcionar. (Prometo volver a esto más tarde si tengo tiempo)

Si tuviera más tiempo (y un nuevo código de wordpress aquí) probablemente integraría esto en la nueva barra de administración con add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 ); (ya prometí volver a esto)

2: debe tener los archivos de idiomas enumerados dentro de la carpeta "languages" en wp-content (¿mejor?) o wp-include. con respecto a este punto, el código es solo una prueba de concepto, y por supuesto, si uno tiene más tiempo, el menú se debe construir de forma dinámica y no como se hace aquí.

3 - su WPLANG en la configuración debería estar vacío. No estoy seguro de que funcione en las nuevas versiones de wp si ya hay un idioma configurado.

4: es una simple prueba sintetizada y parafraseada del concepto basada en lo que se vio en el código qtranslate (también en la versión antigua). Por lo tanto, la mayoría de las cosas se hacen de manera "rápida", no necesariamente de la manera "correcta" ( Como agregar JS, no hay un dominio de texto dedicado, etc.

EDITAR II

alguien tiene suerte hoy! (Retraso de vuelo)

Desde que buscabas "ideas" para los enfoques, aquí hay otra famosa.

No cabrá en un complemento, o en realidad en ningún otro entorno no exclusivo, pero podría darle otra dirección sobre cómo manejar las "cosas del navegador".

Esto le permitirá a uno obtener el idioma con un GET como: <a href="index.php?lang=de">German</a> o <a href="whatever.php?lang=ml">my Language</a>

Para usar, puedes crear un código (llamémoslo 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', '');
        }
    }
 }

ahora, en wp-config, justo antes de la constante WPLANG, debemos incluir nuestro código.

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

Ahora, obviamente, sería mejor agregar algunas cookies a la mezcla para almacenar los idiomas.

EDITAR III

Prometí volver a este tema más adelante. Aquí se explica cómo (de una manera no muy correcta y primitiva) podría integrarse dentro de la barra de administración (en lugar del menú de ayuda contextual)

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

Simplemente reemplace esta función (o agregue) al código antiguo (el no original de OOP sin plugin).

Como dije, no tengo una nueva instalación de wordpress aquí en local que tenga la barra de administración, pero debería funcionar.

(y, de nuevo, puede que no funcione ... pero estoy seguro de que podría solucionarlo si realmente lo desea, incluso aunque no sea OOP) :-)

tengo que correr ahora. Espero que ayude de alguna manera.

EDITAR IV - se modificó la edición III a la versión de trabajo para la barra de menú de administración (al menos en mi wp 3.4)

ya que no tenía una instalación de trabajo de 3.4, y ahora regresé y lo hice, he editado la solución Edit III, y funciona para mí.

Sobre los upvotes, no podría importarme menos. Y no necesito ninguna "recompensa" (sean lo que sean ...) Es solo por el ejercicio que deberías dárselo al autor de qTranslate. :-) a pesar del hecho de que no es OOP, es un plugin genious con mucho para aprender en muchas áreas. considerando el "cuándo" de este lanzamiento del plugin, es incluso increíble. vale la pena el indescriptible esfuerzo de leer un código NO OOP, incluso si no lo es, OOP. E incluso si no está correctamente sangrado (¡Dios mío!).

    
respondido por el krembo99 05.12.2011 - 21:30

Lea otras preguntas en las etiquetas