ボタンをクリックして言語を変更する


21

目標は、ボタン/選択ドロップダウンなどを提供して、パブリックインターフェイスを1)その場で切り替えることです。

私が探しているもの

  • プラグインまたはテーマコード...
  • ... またはアイデア
  • 回避load_textdomain()策を使用すると、.po / .moファイルへの翻訳を残すことができます
  • textdomain関数に依存しない場合に、文字列をインターフェイスに解析する方法に関するアイデア(例:ajax / plain php / ini、json、xmlファイル)

注意:

1)異なる言語での公開ではありません。

2)実際のドロップダウン/ボタンなどを作成するためのコードは必要ありません。UIの文字列を提供するコード/システムについてのみです。

ありがとう!


1
ページの更新に落ち着くことができる場合は、WPLANG定数を再定義することもできます。多言語コンテンツのある2つのサイトで、多言語プラグインがUI変換のトリガーに失敗した場合、それを行っています。それがAJAX / JSONソリューションでなければならない場合、私はどのように支援するのか分からないでしょう。
ヨハネスポール

@JohannesPilleどのポイント/フックで切り替えますか?Btw:それを答えに移してください。既に賛成票を投じる価値があります。ありがとう。
カイザー

私はプラグインでそれをやっており、フックは関係していません。それはかなり汚い修正であり、私はそれをそれほど誇りに思っていませんが、それはその時に仕事を成し遂げました。このpastebinでプラグインのコードを確認できます。それがすることは自明です。これをコピーしたサイトでは、WPMLの最新の無料バージョンを使用しています。結構なもので、答えに移しました。
ヨハネスポール

pastebin URLは無効になっているようです。
PapaFreud

@JohannesPille Qの更新としてコードを投稿するか、期限切れにならないペーストビンを追加しますか?
カイザー

回答:


15

最も簡単な(最も簡単な)方法は、ロケールフィルターを使用することです(内部get_locale())。

最初に、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;
}

私はこれをグローバル関数として残しました、便利かもしれません...?クラス内にラップしたプラグインの残りの部分。

選択可能な言語のドロップダウンが作成されます。

欠点

  • wp-content/languagesフォームのファイルを検索しますxx_xx.mo。その形式ではない場合(すべての.moファイルがそうではない場合)、プラグインはそれを認識しません!
  • ドロップダウンには選択されたロケールのリストが表示されますが、これらはロケールの「xx_xx」形式で表示され、人間に優しい方法ではありません-アイデアはありますか?
  • $locale言語以外の何かを?その場合、ロケールを同じにすることは可能ですが、代替の翻訳を提供します。それはかなり厄介ですが...

コード

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
賛成票を投じました(すべてのインラインコメントについても同様です)。バウンティが設定され、許可されるとすぐにあなたに授与されます(23時間左-忘れた場合はそれを指してください)。
カイザー

2
この質問への回答を反映するように更新されました。
スティーブンハリス

N1ce 1。ブックマーク済み。+1
ヨハネスポール

'wp-admin/includes/ms.php'ネットワークサイトを更新するための管理者通知をトリガーに含めるだけであることに気づきました(単一サイトの場合!)。format_code_lang()カスタム関数内で複製する必要があるかもしれません。
スティーブンハリス

クリーンアップでGistを追加しました -現在プラグインフォルダーをいじっているので、テストする時間がありませんでした。これは、他のプラグインが機能しないことを意味します。あなたが提供された要点と多分fork / updateで作業できることを願っています。賞金は30分で授与できますが、今すぐ退去しなければならないので、明日送ります。すべての作業に感謝-デフォルトのインストールである必要があります:)
kaiser

5

ページの更新に落ち着くことができる場合は、WPLANG定数を再定義することもできます。多言語コンテンツのある2つのサイトで、多言語プラグインがUI変換のトリガーに失敗した場合、それを行っています。


うーん、上記のコードを(同じajaxリクエストで)実行した後、ボタンのオンクリックなどで、ajaxを使用してページの本文またはhtmlタグ全体を置き換えることができます。
ジョシュアアベナザー

+1。ペーストビンを見ただけです。これは、セットアップがhttp://example.com/language/whatever/正しいことを意味しますか?
カイザー

@kaiser Yup、それはコードが由来するサイトのセットアップです。UI言語のみに関心がある場合は、URLクエリ文字列を渡すか、次のページロード時に$_SESSION再定義をトリガーする変数を設定するWPLANG必要があります。多言語サイトでこれを複製する場合は、pastebinのコメントにあるように、そのコードはWPML(最後の無料バージョン)で動作することに注意してください。これらのURIは物理的ではなく、mod_rewriteapacheモジュールを介して書き換えられるため、qTranslateで1対1に複製することはできません。調整できるとは思いますが、「そのまま」では機能しません。
ヨハネスポール

qTranslateやWPMLは使用しません。それは本当にUI言語についてのみです。Ad $_SESSION)私の問題は、彼らが扱うのがかなり難しく、グローバルと配列の間のスタッフが簡単に混同される可能性があることです。したがって、変更する方法を見つけようとするWPLANG場合、ある要求から別の要求にそれを与えるための堅実な方法を見つける必要があります。たぶんadd_query_arg/get_query_var...トリックを行います
カイザー

私はこれについてもう一度考えていました(ソリューションはまだプロジェクトに組み込まれていません):これをajaxにラップできますか?これを回避する最善の方法だと思います。Qを閉じて解決策としてマークしたい:)ありがとう。
カイザー

2

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

あなたが必要なものです...

編集 -コメントの後。最初に-downvotesトレントに貢献したすべての人に感謝します。(これは、頻繁にアクセスしない場合に発生することです:-))

now-スイッチを処理する関数はqtranslate-coreにあります。(多かれ少なかれ80行目から始まります-必要なバージョンによって異なります。)

NOT OOPコードを調べることはできず、他に何もすることはないので、合成に10分かかりました。つまり、OOP以外のコードを別のOOP以外のコードでコンパイルします。

(ごめん、原始的なオールドスクールはこちら)

私が質問を理解したと仮定します&&コードを管理者用にしたいと仮定します&&あなたが望むならそれをフロントエンドに移植する方法を知っていると仮定すると&&コードが最適でないと理解すると仮定します:

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

備考 :

1-これは10分で構築されました。空港でローカルマシンで。私がこれを言う理由は、私がここに持っている唯一の準備ができた利用可能なワードプレスインストールがかなり古いことです。(2.9と思う)。

つまり、新しいdiv構造が(タブ付きで)最近導入されたという事実により、おそらくコンテキストメニューdivの下に言語メニューが表示されますが、それでも機能するはずです。(時間があれば、後でこれに戻ることを約束します)

もっと時間があれば(そしてここに新しいワードプレスのコードがあれば)、おそらくこれを新しい管理バーに統合するでしょうadd_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 );(私はすでにこれに戻ることをすでに約束しました)

2-wp-content(better ??)またはwp-includeの「languages」フォルダー内にリストされた言語ファイルがあるはずです。この点に関して-コードは概念の証明に過ぎません-そしてもちろん時間があれば、ここでやるのではなく、動的な方法でメニューを構築する必要があります。

3-configのWPLANGは空でなければなりません。言語が既に設定されている場合、新しいwpバージョンで動作するかどうかはわかりません。

4-これは、qtranslateコード(古いバージョンでも)で作成されたものに基づいて構築された、単純な合成された言い換えの概念実証です。 、専用のテキストドメインなどはありません。)。

EDIT II

今日は誰かがラッキーです!(フライト遅延 )

アプローチの「アイデア」を探していたので、もう1つの有名なものを紹介します。

プラグイン、または実際には他の非排他的な環境には収まりませんが、「ブラウザ」を処理する方法として別の方向性を与える可能性があります。

これは、1つのようなGETと言語を取得できるようになります:<a href="index.php?lang=de">German</a>または<a href="whatever.php?lang=ml">my Language</a>

を使用するには、コードを作成できます(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', '');
        }
    }
 }

今、WPLANG定数の直前のwp-configで、コードを含める必要があります。

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

さて、明らかに言語を保存するためにいくつかのクッキーをミックスに追加する方が良いでしょう。

編集III

私は後でこれに戻ることを約束しました-これは(contextual-help-menuの代わりに)adminバー内にどのように(非常に正しくない原始的な方法で)統合できるかです

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

この関数を古いコード(元のNON-OOP非プラグイン)に置き換える(または追加する)だけです。

私が言ったように、ローカルにadmin-barを備えた新しいワードプレスのインストールはありませんが、動作するはずです。

(そして再び、それはうまくいかないかもしれません...しかし、あなたが本当に望むならそれを修正できると確信しています-それがOOPではないと思ったとしても):-)

今走らなきゃ それが何らかの形で役立つことを願っています。

編集IV-編集メニューIIIを管理メニューバーの作業バージョンに変更(少なくとも私のwp 3.4で)

3.4のインストールが機能していなかったので-そして今戻ってきて-Edit IIIソリューションを編集しました-そしてそれは私のために働きます。

賛成票については、あまり気にすることはできませんでした。そして、私は「賞金」を必要としません(それらが何であれ..)それはあなたがおそらくqTranslateの作者にそれを与えるべき運動のためでした。:-)それはOOPではないという事実にもかかわらず-それは多くの分野で学ぶべきたくさんの素晴らしいプラグインです。このプラグインリリースの「いつ」を考慮すると、それは驚くべきことです。NON OOPコードを読めないほどの努力に値する-それがOOPでなくても-OOP。そして、たとえ正しくインデントされていなくても(良い神!)。


3
このコードの深さに埋もれたソリューションがあるかもしれませんが、OOPで書かれていないため、すべての方法を理解することはほぼ不可能です。言語検出の正確な場所(ブラウザの内容)とgettext文字列のフィルタリング方法がわかっている場合は、お知らせください。
カイザー

1
@kaiser-「ブラウザ関連」の編集Iを参照してください。
krembo99

1
@kaiser ..と「ブラウザのもの」については編集IIを、「ブラウザ(もの)」内に「ブラウザのもの」を組み込む方法については編集IIIを参照してください。
krembo99

わかりました、あなたの努力のために、私はそれを賛成しました(ここに戻るために下向きではありません)。クッキーを使用するアイデアは素晴らしいです。とにかく、いくつかの注意事項があります:Edit IIはの後にエラーをスローしますrequire()define()同じ文字列で2回使用することはできません。Edit IIIには言語に関する問題がいくつかあります。選択en_USしても何も起こりませんが(?)、de_DEそれはEnglish;)に設定されます。要約すると、私は賞金を授与し、完全で実用的な答えを得るために(たとえばStephenHarrisに)配ります。あなたがそのような何かを得たならば、あなたの答えを更新してください(クッキーアプローチは面白い)、そして、私はあなたに報奨金を加えて、報いるかもしれません。
カイザー

私にコメントを残さないでください。回答を編集して、誰もがあなたのアイデアを読み通せるようにします。補足imhoの外部コードを常にPlugin / MU-Plugin / Theme / DropInとして追加して、移動可能にする必要があります。
カイザー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.