Bir düğmeye tıklayarak dili değiştirin


21

Amaç, genel arayüz 1) dilini anında değiştirmek için bir düğme / seçim açılır veya benzeri sunmaktır .

Ne arıyorum

  • Eklenti veya Tema Kodu ...
  • ... veya Fikirler
  • Etrafında bir load_textdomain()alıştırma kullanmak, çeviri işlemini .po / .mo dosyalarına bırakmaktan memnuniyet duyar
  • Bazı textdomain işlevine dayanmadığında, dizelerin arayüze nasıl ayrıştırılacağına ilişkin fikirler (ör. Ajax / plain php / ini, json, xml dosyaları).

Not:

1) Farklı dillerde yayın yapmakla ilgili değil.

2) Gerçek açılan / düğme / işlem yapmak için koda ihtiyacım yok. Sadece UI için dizeleri sağlayan kod / sistemle ilgilidir.

Teşekkürler!


1
Sayfa yenilemeye WPLANGkarar verebilirseniz , sabitin yeniden tanımlanması bir seçenek olabilir. Bunu, çok dilli eklentinin kullanıcı arayüzü çevirisini tetikleyemediği, çok dilli içeriğe sahip iki sitede yapıyorum. Bir AJAX / JSON çözümü olması gerekiyorsa, nasıl yardım edeceğimi bilemem.
Johannes Pille,

@JohannesPille Hangi noktada / kancada geçiş yaparsınız? Btw: Bunu bir cevaba taşıyabilir misin? Zaten bir yukarı oy değer. Teşekkürler.
kaiser

Ben bir eklenti yapıyorum, ilgili kanca yok. Oldukça kirli bir düzeltme ve bununla gurur duymuyorum, ama o zaman işi hallettim. Eklentinin kodunu bu pastebin'de görebilirsiniz . Yaptığı şey kendini açıklayıcı. Bunu kopyaladığım site WPML'nin son ücretsiz sürümünü kullanıyor. Adil enuff, bir cevaba taşıdı.
Johannes Pille

Pastebin URL'si ölü gibi görünüyor.
PapaFreud

@JohannesPille Kodunuzu Q'nuza güncelleme olarak göndermeyi veya süresi dolmayan bir pastebin eklemeyi düşünür müsünüz?
kaiser

Yanıtlar:


15

Şimdiye kadar en iyi (en kolay) yol yerel filtre kullanmaktır (içeride get_locale()).

İlk önce, localefiltrede kullanılacak farklı bir dili almak için hızlı bir işlev kurun .

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

Bunu global bir işlev olarak bıraktım, kullanışlı olabilir ...? Eklentinin geri kalanı bir sınıfa sarıldım.

Seçebileceğiniz olası dillerin bir açılanını oluşturur.

Dezavantajları

  • wp-content/languagesFormdaki dosyaları arar xx_xx.mo. Bu formda değilse (tüm .mo dosyaları değil), eklenti açılmaz!
  • Açılan menü, aralarından seçim yapabileceğiniz yerel ayarların bir listesini verir, ancak bunlar yerel ayarların 'xx_xx` biçiminde gösterilir, insan dostu bir yöntem değil - herhangi bir fikir ??
  • Dilden $localebaşka bir şey yapar mı ? Öyleyse, yerel ayarları aynı hale getirmek hala mümkündür, ancak alternatif çeviriler sağlayın. Bu çok daha karışık ...

Kod

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
Olumlu oylama (tüm satır içi yorumlar için de gülünç). Ödül belirlenir ve izin verildiğinde size en kısa sürede verilir (unutursam 23h sola işaret et).
kaiser

2
Bu sorunun cevabını yansıtacak şekilde güncellendi .
Stephen Harris

N1ce bir. Yer işaretli. +1
Johannes Pille,

Şunu da ekledim ki 'wp-admin/includes/ms.php', ağ sitelerinizi güncellemek için yalnızca bir site olduğunuzda! O olabilir format_code_lang(), özel bir işlevi içinde çoğaltılamaz gerekecektir.
Stephen Harris

Temizliği olan bir Gist ekledim - şu anda eklenti klasörleriyle uğraştığım için test etmeye hiç zamanım olmadı ve bu da başka bir eklentinin çalışmadığı anlamına geliyor. Umarım sağlanan özü ve belki de çatal / güncelleme ile çalışabilirsiniz. Ödülünü yarım saat içinde verebilirim ama şimdi gitmem gerekiyor, o yüzden yarın göndereceğim. Tüm çalışmalarınız için teşekkürler - herhangi bir varsayılan kurulumda olmalıdır :)
kaiser

5

Sayfa yenilemeye WPLANGkarar verebilirseniz , sabitin yeniden tanımlanması bir seçenek olabilir. Bunu, çok dilli eklentinin kullanıcı arayüzü çevirisini tetikleyemediği, çok dilli içeriğe sahip iki sitede yapıyorum.


Hmm .. yukarıdaki kodu yürüttükten sonra (aynı ajax isteğinde), düğmenizi tıklayıp benzeri bir şey yaptıktan sonra, sayfanın gövdesini veya sayfanın tüm html etiketini değiştirmek için ajax kullanabilirsiniz.
Joshua Abenazer 19

+1. Sadece pastöre baktı. Bu, kurulumunuzun http://example.com/language/whatever/doğru olduğu anlamına mı geliyor?
kaiser

@kaiser Yup, kodun geldiği sitedeki kurulum. Yalnızca UI dilini önemsiyorsanız, bir URL sorgu dizesini geçmek veya bir sonraki sayfa yükleme $_SESSIONişleminin yeniden tanımlanmasını tetiklemek için bir değişken ayarlamak WPLANGgerekir. Bunu çok dilli bir sitede çoğaltmak istiyorsanız, pastebin ile yaptığı açıklamada, kodun WPML ile çalıştığını, son sürümün ücretsiz olduğunu unutmayın. QTranslate ile 1'den 1'e kopyalanamaz, çünkü bu URI'ler fiziksel değildir, ancak mod_rewriteapache modülü aracılığıyla yeniden yazılır . Ayarlanabileceğinden eminim ama "olduğu gibi" işe yaramayacak.
Johannes Pille

QTranslate veya WPML kullanmayacağım. Gerçekten sadece UI dili ile ilgili. Reklam $_SESSION) Benim sorunum şu ki, ele alınması oldukça güç ve dünya ile dizi arasındaki şeyleri kolayca karıştırabilirler. Yani, değişecek bir yol bulmaya çalışırsam WPLANG, o zaman bir istekten diğerine vermek için sağlam bir yol bulmalıyım. Belki add_query_arg/get_query_varhile yapacağız ...
kaiser

Sadece bunu tekrar düşünüyordum (çözüm hala projeye dahil değil): Bunu bir ajax'a sarabilir misiniz? Bunun üstesinden gelmenin en iyi yolu olacağını düşünüyorum. Q'yu kapatıp çözüm olarak işaretlemek istiyorum :) Teşekkürler.
kaiser

2

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

ihtiyacın olan şey ...

Düzenle I - yorumdan sonra. İlk olarak - torrent indirmeye katkıda bulunan herkese teşekkürler. (biri yeterince sık ziyaret etmediğinde olan budur: -))

now - Şalteri kullanan fonksiyon qtranslate çekirdeğindedir. (80. satırdan az ya da çok başlar - istediğiniz sürüme göre değişir.)

Bir NOT OOP koduna bakamadığınızdan ve şimdi yapacak başka bir şeyim olmadığı için - sentezlemem için 10 dakika sürdüm, parola tüm OOp olmayanları sizin için başka bir OOP olmayan kodla derledim.

(üzgünüm, - burada ilkel eski skool)

& & 'Kodunu yönetici olarak kullanmak istediğinizi farz edersem & &' sorusunu anladığımı farz edersek & & nbsp; kodun optimal olmadığını anladığınızı varsayarak & nbsp;

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

UYARILAR :

1 - Bu 10 dakikada inşa edildi. havaalanında iken yerel makinede. Bunu söylememin nedeni, burada sahip olduğum tek hazır wordpress kurulumunun oldukça eski olması. (2.9 sanırım).

Bu, muhtemelen yeni bir div yapısının yakın zamanda tanıtılmış olması (sekmeli) - bağlamsal yardım divinin altında dil menüsünün görüneceği anlamına gelir - ama yine de çalışması gerekir. (Zamanım olursa tekrar buna döneceğime söz veriyorum)

Daha fazla zamanım olsaydı (ve burada yeni bir wordpress kodu), bunu muhtemelen yeni admin-bar'a entegre ederdim add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 );(zaten buna geri döneceğime söz verdim)

2 - wp-content (daha iyi ??) veya wp-include'taki “diller” klasörü içinde listelenen dil dosyalarına sahip olmalısınız. Bu noktaya ilişkin olarak - kod yalnızca bir kavram kanıtıdır - ve elbette eğer daha fazla zaman varsa, menü dinamik bir şekilde yapılmalı ve burada yapılmayacak şekilde yapılmalıdır.

3 - config içindeki WPLANG'iniz boş olmalıdır. Bir dil ayarlanmışsa, daha yeni wp sürümlerinde çalışacağından emin değilim.

4 - qtranslate kodunda (aynı zamanda eski versiyonda) görülen şeyin üzerine inşa edilmiş basit bir sentezlenmiş ve tasvir edilmiş bir kavram kanıtıdır - bu yüzden işlerin çoğu "hızlı" şekilde yapılır, mutlaka "doğru" şekilde değil (JS eklemek gibi) , özel metin etki alanı vb.

EDIT II

bugün birisi şanslı! (Uçuş erteleme )

Yaklaşımlar için "fikirler" aradığına göre, işte bir başka ünlü.

Bir eklentiye veya aslında başka hiçbir özel olmayan ortama sığmayacak, ancak "Tarayıcı öğelerini" nasıl kullanacağınız konusunda size başka bir yön verebilir.

Bu, birinin dili GET ile almasını sağlar: <a href="index.php?lang=de">German</a>veya<a href="whatever.php?lang=ml">my Language</a>

Kullanmak için bir kod oluşturabilirsiniz (ha wp-langswitch.php diyelim)

 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', '');
        }
    }
 }

Şimdi, wp-config'de, WPLANG sabitinin hemen öncesinde, kodumuzu eklememiz gerekir.

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

Şimdi - tabii ki dilleri saklamak için karışıma biraz çerez eklemek daha iyi olurdu.

EDIT III

Buna daha sonra geri döneceğime söz verdim - işte (çok doğru olmayan ve ilkel bir şekilde) yönetici çubuğuna (bağlamsal yardım menüsü yerine) nasıl entegre edilebileceği.

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

Sadece bu fonksiyonu değiştirin (veya ekleyin) eski koda (orijinal NON - OOP eklentisi yok).

Dediğim gibi, burada admin-bar özelliğine sahip yerel bir wordpress kurulumum yok - ancak çalışması gerekiyor.

(ve sonra tekrar, işe yaramayabilir ... ama gerçekten istersen onu düzeltebileceğinden eminim - hatta OOP olmadığını düşündüm) :-)

Şimdi koşmalıyım. Umarım bir şekilde yardımcı olur.

DÜZENLEME IV - yönetici menü çubuğu için çalışma düzenini III olarak değiştirdi (en azından benim 3.4)

3.4 çalışan bir kurulumum olmadığı için - ve şimdi geri döndüm ve yaptım - Edit III çözümünü düzenledim - ve bu benim için çalışıyor.

Olumlu oylar hakkında daha az umursayamazdım. Ve herhangi bir “ödül” e ihtiyacım yok (bunlar ne olursa olsun ..) Bu, sadece onu qTranslate'in yazarına vermeniz gereken alıştırmalar içindi. :-) OOP olmadığı gerçeğine rağmen - birçok alanda öğrenilecek çok şeyi olan geniş bir eklenti. Bu eklenti sürümünün "ne zaman" göz önüne alındığında bile şaşırtıcı. OOP olmayan bir NOP kodu okuma tarif edilemez bir çabaya değer - OOP olmasa bile -. Ve doğru girintili olmasa bile (iyi tanrı!).


3
Belki de bu kodun derinliklerine gömülmüş bir çözüm vardır, ancak OOP'da yazılmadığı için her yolu bulmak imkansızdır. Dil algılamanın tam olarak nereye oturduğunu (tarayıcı öğesi) ve gettext dizelerini nasıl filtrelediğini biliyorsanız, lütfen bana bildirin.
kaiser

1
@kaiser - bkz. "browser stuff" için I düzenleme.
krembo99

1
@kaiser ..ve daha fazla "tarayıcı öğesi" için düzenleme II’ye bakın - ve "tarayıcı öğesi" ni "tarayıcı (sayfalar)" içine nasıl dahil edeceğiniz için III'ü düzenleyin.
krembo99 9

Tamam, çaban için çabaladım. Kurabiye kullanma fikri güzel. Her neyse, işte bazı notlar: Edit II, bundan sonra bir hata verecektir require(). define()Aynı ipte iki kez kullanamazsınız . Düzenleme III'ün dillerle ilgili bazı problemleri vardır. Seçmek en_UShiçbir şey yapmaz (?), Ancak ;) olarak de_DEayarlardı English. Özetlemek gerekirse: Ben ödüller veririm ve onları tam ve çalışan bir cevap için (örneğin StephenHarris) olarak veririm. Böyle bir şey varsa, lütfen cevabınızı güncelleyin (ilginç çerez yaklaşımı) ve ben size bir ödül ekleyip ödüllendirebilirim.
kaiser

Lütfen benim için yorum bırakmayın. Cevabınızda düzenlemeler yapın, böylece herkes düşüncelerinizi okuyabilir. Sidenote: imho dış kod her zaman Eklenti / MU-Plugin / Tema / dropin o hareketli hale getirmek için eklenmelidir.
kaiser
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.