Ubah bahasa dengan mengklik tombol

21

Tujuannya adalah untuk menawarkan tombol / pilih drop-down atau serupa untuk mengganti antarmuka publik 1) bahasa dengan cepat.

Apa yang saya cari

  • Plugin atau Kode Tema ...
  • ... atau Gagasan
  • Menggunakan work-around with load_textdomain()akan dihargai untuk meninggalkan terjemahan ke file .po / .mo
  • Gagasan tentang cara mem-parsing string ke antarmuka (mis. Ajax / plain php / ini, json, file xml) saat tidak bergantung pada beberapa fungsi domain teks

catatan:

1) Ini bukan tentang penerbitan dalam berbagai bahasa.

2) Saya tidak perlu kode untuk membuat drop-down / tombol / yang sebenarnya. Ini hanya tentang kode / sistem yang memberikan string untuk UI.

Terima kasih!

kaisar
sumber
1
Jika Anda dapat menerima penyegaran halaman, mendefinisikan ulang WPLANGkonstanta bisa menjadi pilihan. Saya melakukan itu di dua situs dengan konten multibahasa di mana plugin multilingualitas gagal memicu terjemahan UI. Jika itu harus menjadi solusi AJAX / JSON, saya tidak akan tahu bagaimana cara membantu.
Johannes Pille
@JohannesPille Di titik / kait mana Anda harus beralih? Btw: Bisakah Anda memindahkannya ke suatu jawaban. Sudah bernilai suara. Terima kasih.
kaiser
Saya melakukannya dalam sebuah plugin, tidak ada kaitan yang terlibat. Ini adalah perbaikan yang sangat kotor dan saya tidak terlalu bangga akan hal itu, tetapi itu menyelesaikan pekerjaan pada saat itu. Anda dapat melihat kode plugin di pastebin ini . Apa yang dilakukannya cukup jelas. Situs tempat saya menyalin ini menggunakan versi gratis terakhir WPML. Adil, pindah ke sebuah jawaban.
Johannes Pille
URL pastebin tampaknya sudah mati.
PapaFreud
@JohannesPille Maukah Anda memposting kode Anda sebagai pembaruan untuk Q Anda, atau menambahkan pastebin yang tidak kedaluwarsa?
kaiser

Jawaban:

15

Sejauh ini cara terbaik (termudah) adalah menggunakan filter lokal (di dalam get_locale()).

Pertama-tama, atur fungsi cepat untuk mengambil bahasa yang berbeda untuk digunakan pada localefilter.

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

Saya meninggalkan ini sebagai fungsi global, mungkin berguna ...? Sisa plug-in yang saya bungkus di dalam kelas.

Ini menciptakan drop-down bahasa yang memungkinkan dari mana Anda dapat memilih.

Kekurangannya

  • Mencari wp-content/languagesfile formulir xx_xx.mo. Jika bukan dari bentuk itu (tidak semua file .mo), plug-in tidak akan menerimanya!
  • Drop down memberikan daftar lokal yang ditemukan untuk dipilih, tetapi ini ditampilkan dalam format 'xx_xx` lokal, bukan cara yang ramah manusia - ada ide ??
  • Apakah $localemelakukan hal lain selain bahasa? Jika demikian, masih mungkin untuk mendapatkan lokasi yang sama, tetapi berikan terjemahan alternatif. Ini jauh lebih berantakan ...

Kode

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();
Stephen Harris
sumber
1
Upvote selesai (penuh dengan semua komentar inline juga). Bounty diatur dan akan diberikan kepada Anda segera, setelah saya diizinkan (23h kiri - tunjukkan saya jika saya lupa).
kaiser
2
Diperbarui untuk mencerminkan jawaban atas pertanyaan ini .
Stephen Harris
Satu lagi. Ditandai. +1
Johannes Pille
Saya perhatikan bahwa hanya termasuk 'wp-admin/includes/ms.php'memicu pemberitahuan admin untuk memperbarui situs jaringan Anda (ketika Anda adalah satu situs!). Mungkin format_code_lang()perlu digandakan di dalam fungsi khusus.
Stephen Harris
Saya menambahkan inti dengan pembersihan saya - tidak punya waktu untuk mengujinya, karena saya mengacaukan folder plugin saat ini dan ini berarti tidak ada plugin lain yang berfungsi. Semoga Anda bisa bekerja dengan intisari yang disediakan dan mungkin garpu / pembaruan. Saya dapat memberi hadiah dalam setengah jam, tetapi harus pergi sekarang, jadi saya akan mengirimkannya besok. Terima kasih untuk semua pekerjaan Anda - harus dalam instalasi default :)
kaiser
5

Jika Anda dapat menerima penyegaran halaman, mendefinisikan ulang WPLANGkonstanta bisa menjadi pilihan. Saya melakukan itu di dua situs dengan konten multibahasa di mana plugin multilingualitas gagal memicu terjemahan UI.

Johannes Pille
sumber
Hmm .. Anda bisa menggunakan ajax untuk mengganti badan atau seluruh tag html halaman dalam hal ini, setelah mengeksekusi kode di atas (dalam permintaan ajax yang sama), klik tombol Anda atau sesuatu seperti itu.
Joshua Abenazer
+1. Hanya melihat pastebin kamu. Ini berarti pengaturan Anda http://example.com/language/whatever/benar, bukan?
kaiser
@kaiser Yup, itulah pengaturan di situs tempat kode berasal. Jika Anda hanya peduli dengan bahasa UI, meneruskan string kueri URL atau mengatur $_SESSIONvariabel untuk memicu pendefinisian ulang WPLANGpada pageload berikutnya harus dilakukan. Jika Anda ingin mereplikasi ini di situs multibahasa, catat bahwa seperti komentar pada pastebin, kode di dalamnya berfungsi dengan WPML, versi gratis terakhir. Itu tidak dapat direplikasi 1 ke 1 dengan qTranslate, karena URI itu bukan fisik tetapi ditulis ulang melalui mod_rewritemodul apache. Saya yakin itu bisa disesuaikan, tetapi tidak akan berfungsi "sebagaimana adanya".
Johannes Pille
Saya tidak akan menggunakan qTranslate atau WPML. Ini benar-benar hanya tentang bahasa UI. Ad $_SESSION) Masalah saya adalah bahwa afaik mereka cukup sulit untuk ditangani dan hal-hal antara global dan array dapat bercampur dengan mudah. Jadi, jika saya mencoba mencari cara untuk berubah WPLANG, maka saya perlu menemukan cara yang kuat untuk memberikannya dari satu permintaan ke yang lain. Mungkin add_query_arg/get_query_varakan melakukan trik ...
kaiser
Saya hanya berpikir tentang ini lagi (solusi masih belum dibangun ke dalam proyek): Bisakah Anda membungkus ini menjadi beberapa ajax? Saya pikir ini akan menjadi cara terbaik untuk mengatasi ini. Saya ingin menutup Q dan menandainya sebagai solusi :) Terima kasih.
kaiser
2

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

adalah yang kamu butuhkan ...

Edit I - setelah komentar. Pertama - terima kasih untuk semua yang berkontribusi dalam torrent downvotes. (Inilah yang terjadi ketika seseorang tidak cukup sering mengunjungi: -)

now - Fungsi yang menangani switch adalah dalam qtranslate-core. (dimulai pada baris 80 lebih atau kurang - tergantung pada versi yang Anda inginkan.)

Karena Anda tidak dapat melihat kode BUKAN OOP, dan saya sekarang tidak memiliki hal lain untuk dilakukan - saya memerlukan waktu 10 menit untuk mensintesis, parafrase mengkompilasi non-OOp itu dengan kode non-OOP lain untuk Anda.

(Maaf, - skool tua primitif di sini)

Dengan anggapan saya memahami pertanyaan && Dengan asumsi Anda menginginkan kode untuk admin && dengan asumsi Anda akan tahu cara mengirimnya ke ujung depan jika Anda ingin && dengan asumsi Anda memahami bahwa kode tersebut tidak 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.
?>

KETERANGAN:

1 - Ini dibangun dalam 10 menit. pada mesin lokal saat di bandara. Alasan mengapa saya mengatakan ini adalah bahwa satu-satunya instalasi wordpress yang tersedia yang saya miliki di sini sudah cukup tua. (2,9 saya pikir).

Ini berarti bahwa mungkin menu bahasa akan muncul DI BAWAH div bantuan kontekstual, karena fakta bahwa struktur div baru baru-baru ini diperkenalkan (dengan tab) - tetapi tetap harus berfungsi. (Saya berjanji untuk kembali lagi nanti jika saya punya waktu)

Jika saya punya lebih banyak waktu (dan kode wordpress baru di sini) saya mungkin akan mengintegrasikan ini di admin-bar baru dengan add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 );(saya sudah berjanji untuk kembali ke ini)

2 - Anda harus memiliki file bahasa yang terdaftar di dalam folder "bahasa" di wp-content (lebih baik ??) atau wp-include. mengenai hal ini - kode hanya merupakan bukti konsep - dan tentu saja jika seseorang memiliki lebih banyak waktu menu harus dibangun secara dinamis dan tidak suka dilakukan di sini.

3 - WPLANG Anda dalam konfigurasi harus kosong. Saya tidak yakin ini akan berfungsi pada versi wp yang lebih baru jika bahasa sudah diatur.

4 - ini adalah bukti sederhana konsep yang disintesis dan diparafrasekan yang dibangun di atas apa yang terlihat dalam kode qtranslate (juga versi lama) - sehingga sebagian besar hal dilakukan dengan cara "cepat", belum tentu cara "benar" (seperti menambahkan JS , tidak ada domain teks khusus, dll.).

EDIT II

seseorang beruntung hari ini! (Penundaan penerbangan )

Karena Anda mencari "ide" untuk pendekatan, berikut ini adalah salah satu yang terkenal.

Ini tidak akan cocok dengan plugin, atau sebenarnya lingkungan non-eksklusif lainnya, tetapi mungkin memberi Anda arahan lain bagaimana menangani "hal-hal Browser".

Ini akan memungkinkan seseorang untuk mendapatkan bahasa dengan GET seperti: <a href="index.php?lang=de">German</a>atau<a href="whatever.php?lang=ml">my Language</a>

Untuk menggunakan, Anda dapat membuat kode (sebut saja 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', '');
        }
    }
 }

sekarang, di wp-config, sesaat sebelum konstanta WPLANG, kita perlu memasukkan kode kita.

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

Sekarang - jelas akan lebih baik untuk menambahkan beberapa cookie ke dalam campuran untuk menyimpan bahasa.

EDIT III

Saya berjanji untuk kembali ke sini nanti - inilah caranya (dengan cara yang sangat tidak benar dan primitif) dapat diintegrasikan di dalam admin-bar (alih-alih kontekstual-bantuan-menu)

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

Cukup ganti fungsi ini (atau tambahkan) ke kode lama (non-plugin NON - OOP yang asli).

Seperti yang saya katakan, saya tidak memiliki instalasi wordpress baru di sini di lokal yang memiliki fitur admin-bar - tetapi harus bekerja.

(dan sekali lagi, itu mungkin tidak berfungsi ... tapi saya yakin Anda dapat memperbaikinya jika Anda benar-benar ingin - bahkan mengira itu bukan OOP) :-)

harus lari sekarang. semoga membantu entah bagaimana.

EDIT IV - ubah edit III menjadi verion yang berfungsi untuk bilah menu admin (setidaknya di wp 3.4 saya)

karena saya tidak menginstalasi 3.4 - dan sekarang saya kembali dan saya melakukannya - saya telah mengedit solusi Edit III - dan itu berfungsi untuk saya.

Tentang upvotes, saya tidak peduli. Dan saya tidak memerlukan "karunia" (apa pun itu ..) Itu hanya untuk latihan yang Anda harus berikan kepada penulis qTranslate. :-) terlepas dari kenyataan bahwa itu bukan OOP - ini adalah plugin genious dengan banyak hal untuk dipelajari di banyak area. mengingat "kapan" dari rilis plugin ini, itu bahkan luar biasa. sepadan dengan upaya yang tak terlukiskan membaca kode NON OOP - bahkan jika tidak - OOP. Dan bahkan jika itu tidak indentasi benar (tuhan yang baik!).

krembo99
sumber
3
Mungkin ada solusi yang terkubur di dalam kode ini, tetapi hampir tidak mungkin untuk menemukan jalan keluar, karena tidak ditulis dalam OOP. Jika Anda tahu di mana tepatnya pendeteksian bahasa berada (hal-hal browser) dan bagaimana ia memfilter string gettext, beri tahu saya.
kaiser
1
@kaiser - lihat edit I untuk "hal-hal browser".
krembo99
1
@kaiser ..dan lihat edit II untuk lebih banyak "hal browser" - dan edit III untuk cara memasukkan "hal browser" di dalam "browser (barang)".
krembo99
Ok, saya membatalkannya (bukan downvote untuk kembali di sini), atas upaya Anda. Gagasan menggunakan cookie, bagus. Bagaimanapun, ini beberapa catatan: Sunting II akan melempar kesalahan setelah require(). Anda tidak dapat menggunakan define()string yang sama dua kali. Sunting III memiliki beberapa masalah dengan bahasa. Memilih en_UStidak akan melakukan apa-apa (?), Tetapi de_DEakan mengaturnya ke English;). Singkatnya: Saya memberi hadiah dan memberikannya kepada (misalnya StephenHarris) untuk jawaban yang lengkap dan berhasil. Jika Anda mendapatkan sesuatu seperti itu, harap perbarui jawaban Anda (pendekatan cookie menarik) dan saya dapat menambahkan dan memberi Anda hadiah.
kaiser
Tolong jangan tinggalkan komentar untuk saya. Edit jawaban Anda, sehingga semua orang dapat membaca ide-ide Anda. Sidenote: imho kode eksternal harus selalu ditambahkan sebagai Plugin / MU-Plugin / Tema / DropIn agar dapat dipindahkan.
kaiser