Thay đổi ngôn ngữ bằng cách nhấp vào nút


21

Mục tiêu là cung cấp một nút / chọn thả xuống hoặc tương tự để chuyển đổi ngôn ngữ giao diện công cộng 1) khi đang di chuyển.

Những gì tôi đang tìm kiếm

  • Plugin hoặc mã chủ đề ...
  • ... hoặc ý tưởng
  • Sử dụng một công việc xung quanh load_textdomain()sẽ được đánh giá cao để chuyển dịch sang các tệp .po / .mo
  • Ý tưởng về cách phân tích các chuỗi vào giao diện (ví dụ: ajax / plain php / ini, json, xml) khi không dựa vào một số chức năng tên miền văn bản

Chú thích:

1) Đây không phải là về xuất bản bằng các ngôn ngữ khác nhau.

2) Tôi không cần mã để thực hiện thả xuống / nút / bất cứ thứ gì. Đó chỉ là về mã / hệ thống cung cấp các chuỗi cho UI.

Cảm ơn!


1
Nếu bạn có thể giải quyết để làm mới trang, xác định lại WPLANGhằng số có thể là một tùy chọn. Tôi đang làm điều đó trên hai trang web có nội dung đa ngôn ngữ trong đó plugin đa ngôn ngữ không kích hoạt dịch thuật UI. Nếu nó phải là một giải pháp AJAX / JSON, tôi sẽ không biết cách giúp đỡ.
Julian Pille

@JohannesPille Bạn chuyển sang điểm / móc nào? Btw: Bạn có thể chuyển câu trả lời đó không. Đã có giá trị bỏ phiếu lên. Cảm ơn.
kaiser

Tôi đang làm nó trong một plugin, không có hook liên quan. Đó là một sửa chữa khá bẩn và tôi không tự hào về nó, nhưng nó đã hoàn thành công việc vào thời điểm đó. Bạn có thể thấy mã của plugin trong pastebin này . Những gì nó làm là tự giải thích. Trang web tôi đã sao chép này từ việc sử dụng phiên bản WPML miễn phí cuối cùng. Công bằng, chuyển nó đến một câu trả lời.
Julian Pille

URL pastebin dường như đã chết.
PapaFreud

@JohannesPille Bạn có phiền đăng mã của mình dưới dạng cập nhật cho Q của bạn không, hoặc thêm một pastebin không hết hạn?
kaiser

Câu trả lời:


15

Cho đến nay, cách tốt nhất (dễ nhất) là sử dụng bộ lọc ngôn ngữ (bên trong get_locale()).

Trước tiên, hãy thiết lập chức năng nhanh để truy xuất ngôn ngữ khác để sử dụng trên localebộ lọc.

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

Tôi đã để lại chức năng này như một chức năng toàn cầu, có thể có ích ...? Phần còn lại của trình cắm đã được tôi bọc trong một lớp.

Nó tạo ra một ngôn ngữ có thể thả xuống mà bạn có thể chọn.

Hạn chế

  • Tìm kiếm wp-content/languagescác tập tin của mẫu xx_xx.mo. Nếu nó không phải là dạng đó (không phải tất cả các tệp .mo) thì trình cắm sẽ không nhận được nó!
  • Trình đơn thả xuống cung cấp danh sách các địa điểm được tìm thấy để chọn, nhưng chúng được hiển thị theo định dạng 'xx_xx` của địa phương, không phải là cách thân thiện với con người - có ý tưởng nào không ??
  • $localelàm gì khác ngoài ngôn ngữ không? Nếu vậy, vẫn có thể có được ngôn ngữ giống nhau, nhưng cung cấp các bản dịch thay thế. Mặc dù nó lộn xộn hơn nhiều ...

Mật mã

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
Upvote đã hoàn thành (loughing về tất cả các ý kiến ​​nội tuyến là tốt). Bounty được thiết lập và sẽ được trao cho bạn ngay khi tôi được phép (23h còn lại - hãy chỉ cho tôi nếu tôi quên).
kaiser

2
Cập nhật để phản ánh câu trả lời cho câu hỏi này .
Stephen Harris

N1ce một. Đánh dấu trang. +1
Julian Pille

Tôi đã nhận thấy rằng chỉ bao gồm 'wp-admin/includes/ms.php'kích hoạt thông báo quản trị viên để cập nhật các trang web mạng của bạn (khi bạn là một trang web duy nhất!). Nó có thể format_code_lang()sẽ cần được sao chép bên trong một chức năng tùy chỉnh.
Stephen Harris

Tôi đã thêm một Gist với việc dọn dẹp của mình - không có thời gian kiểm tra nó, vì hiện tại tôi đang loay hoay với các thư mục plugin và điều này có nghĩa là không có plugin nào khác hoạt động. Hy vọng bạn có thể làm việc với ý chính được cung cấp và có thể fork / cập nhật. Tôi có thể thưởng tiền thưởng trong nửa giờ, nhưng phải rời đi ngay bây giờ, vì vậy tôi sẽ gửi nó vào ngày mai. Cảm ơn tất cả công việc của bạn - nên có trong bất kỳ cài đặt mặc định nào :)
kaiser

5

Nếu bạn có thể giải quyết để làm mới trang, xác định lại WPLANGhằng số có thể là một tùy chọn. Tôi đang làm điều đó trên hai trang web có nội dung đa ngôn ngữ trong đó plugin đa ngôn ngữ không kích hoạt dịch thuật UI.


Hmm .. bạn có thể sử dụng ajax để thay thế phần thân hoặc toàn bộ thẻ html của trang cho vấn đề đó, sau khi thực thi đoạn mã trên (trong cùng một yêu cầu ajax), onclick nút của bạn hoặc đại loại như thế.
Joshua Abenazer

+1. Chỉ cần nhìn vào pastebin của bạn. Điều này có nghĩa là thiết lập của bạn http://example.com/language/whatever/, phải không?
kaiser

@kaiser Yup, đó là thiết lập trên trang web có mã đến từ đâu. Nếu bạn chỉ quan tâm đến ngôn ngữ UI, việc truyền chuỗi truy vấn URL hoặc đặt $_SESSIONbiến để kích hoạt xác định lại WPLANGkhi tải trang tiếp theo sẽ làm. Nếu bạn quan tâm để sao chép điều này trên một trang web đa ngôn ngữ, lưu ý rằng như nhận xét với pastebin nói, mã trong nó hoạt động với WPML, phiên bản miễn phí cuối cùng. Nó không thể được sao chép từ 1 đến 1 bằng qTranslate, vì các URI đó không phải là vật lý mà được viết lại thông qua mod_rewritemô-đun apache. Tôi chắc chắn rằng nó có thể được điều chỉnh, nhưng sẽ không hoạt động "như hiện tại".
Julian Pille

Tôi sẽ không sử dụng qTranslate hoặc WPML. Nó thực sự chỉ về ngôn ngữ UI. Quảng cáo $_SESSION) Vấn đề của tôi là afaik chúng khá khó xử lý và mọi thứ giữa các thế giới và mảng có thể bị lẫn lộn dễ dàng. Vì vậy, nếu tôi cố gắng tìm cách thay đổi WPLANG, thì tôi cần tìm một cách vững chắc để đưa nó từ yêu cầu này sang yêu cầu khác. Có lẽ add_query_arg/get_query_varsẽ làm được điều đó ...
kaiser

Tôi chỉ nghĩ về điều này một lần nữa (giải pháp vẫn chưa được xây dựng trong dự án): Bạn có thể gói nó vào một số ajax không? Tôi nghĩ rằng đây sẽ là cách tốt nhất để khắc phục điều này. Tôi muốn đóng Q và đánh dấu nó là giải pháp :) Cảm ơn.
kaiser

2

http://www.qianqin.de/qtransTable/

là những gì bạn cần ...

Chỉnh sửa tôi - sau khi bình luận. Đầu tiên - cảm ơn tất cả những người đã đóng góp trong downvote torrent. (đây là những gì xảy ra khi một người không truy cập thường xuyên đủ: -))

ngay bây giờ - Chức năng xử lý công tắc nằm trong qtranslate-core. (bắt đầu ở dòng 80 nhiều hơn hoặc ít hơn - tùy thuộc vào phiên bản bạn muốn.)

Vì bạn không thể xem mã KHÔNG OOP và bây giờ tôi không có gì khác để làm - tôi mất 10 phút để tổng hợp, paraph khẩu biên dịch mà không phải OOp với một mã không OOP khác cho bạn.

(xin lỗi, - skool cũ nguyên thủy ở đây)

Giả sử rằng tôi đã hiểu câu hỏi && Giả sử bạn muốn mã dành cho quản trị viên && giả sử bạn sẽ biết cách chuyển nó sang giao diện người dùng nếu bạn muốn && giả sử bạn hiểu rằng mã không tối ưu:

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

NHẬN XÉT:

1 - Điều này được xây dựng trong 10 phút. trên máy cục bộ khi ở sân bay. Lý do tại sao tôi nói điều này là cài đặt wordpress có sẵn duy nhất mà tôi có ở đây khá cũ. (2.9 Tôi nghĩ).

Điều này có nghĩa là có lẽ menu ngôn ngữ sẽ xuất hiện DƯỚI div trợ giúp theo ngữ cảnh, do thực tế là một cấu trúc div mới đã được giới thiệu gần đây (với các tab) - nhưng nó vẫn hoạt động. (Tôi hứa sẽ quay lại vấn đề này sau nếu tôi có thời gian)

Nếu tôi có nhiều thời gian hơn (và một mã wordpress mới ở đây) tôi có thể sẽ tích hợp mã này vào thanh quản trị mới add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 );(tôi đã hứa sẽ quay lại vấn đề này)

2 - bạn nên có các tệp ngôn ngữ được liệt kê bên trong thư mục "ngôn ngữ" trong nội dung wp (tốt hơn ??) hoặc wp-gộp. liên quan đến điểm này - mã chỉ là một bằng chứng về khái niệm - và tất nhiên nếu ai đó có nhiều thời gian hơn thì menu sẽ được xây dựng theo cách năng động và không giống như được thực hiện ở đây.

3 - WPLANG của bạn trong cấu hình nên trống. Tôi không chắc nó sẽ hoạt động trên các phiên bản wp mới hơn nếu ngôn ngữ đã được đặt.

4 - đó là một bằng chứng khái niệm đơn giản được tổng hợp và diễn giải dựa trên những gì đã thấy trong mã qtranslate (cũng là phiên bản cũ) - vì vậy hầu hết mọi thứ đều được thực hiện theo cách "nhanh chóng", không nhất thiết là cách "đúng" (như thêm JS , không có tên miền văn bản chuyên dụng, v.v.).

EDIT II

hôm nay có người may mắn (Hoãn chuyến bay )

Vì bạn đang tìm kiếm "ý tưởng" cho các phương pháp tiếp cận, đây là một ý tưởng nổi tiếng khác.

Nó sẽ không phù hợp với một plugin, hoặc bất kỳ môi trường không độc quyền nào khác, nhưng nó có thể cung cấp cho bạn một hướng khác là cách xử lý "Nội dung trình duyệt".

Điều này sẽ cho phép một người có được ngôn ngữ với GET như: <a href="index.php?lang=de">German</a>hoặc<a href="whatever.php?lang=ml">my Language</a>

Để sử dụng, bạn có thể tạo một mã (hãy để tên gọi là 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', '');
        }
    }
 }

bây giờ, trong wp-config, ngay trước hằng số WPLANG, chúng ta cần bao gồm mã của chúng tôi.

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

Bây giờ - rõ ràng sẽ tốt hơn nếu thêm một số cookie vào hỗn hợp để lưu trữ ngôn ngữ.

EDIT III

Tôi đã hứa sẽ quay lại vấn đề này sau - đây là cách (theo cách rất không chính xác và nguyên thủy) nó có thể được tích hợp bên trong thanh quản trị (thay vì trình đơn trợ giúp theo ngữ cảnh)

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

Chỉ cần thay thế chức năng này (hoặc thêm) vào mã cũ (NON - OOP ban đầu không phải là plugin).

Như tôi đã nói, tôi không có cài đặt wordpress mới ở đây trên địa phương có tính năng quản trị viên - nhưng nó sẽ hoạt động.

(và sau đó một lần nữa, nó có thể không hoạt động ... nhưng tôi chắc chắn bạn có thể khắc phục điều đó nếu bạn thực sự muốn - thậm chí nghĩ rằng đó không phải là OOP) :-)

phải chạy ngay bây giờ hy vọng nó sẽ giúp

EDIT IV - đã thay đổi chỉnh sửa III thành verion làm việc cho thanh menu của quản trị viên (ít nhất là trên wp 3.4 của tôi)

vì tôi không cài đặt được 3,4 - và bây giờ tôi đã quay lại và tôi làm - tôi đã chỉnh sửa giải pháp Chỉnh sửa III - và nó hoạt động với tôi.

Về upvote, tôi không thể không quan tâm. Và tôi không cần bất kỳ "tiền thưởng" nào (dù đó là những gì có thể ..) Đó chỉ là vì mục đích của bài tập mà bạn có thể đưa nó cho tác giả của qTranslate. :-) mặc dù thực tế rằng nó không phải là OOP - nó là một plugin có nhiều gen để học hỏi trong nhiều lĩnh vực. xem xét "khi nào" của phiên bản plugin này, nó thậm chí còn tuyệt vời. xứng đáng với nỗ lực không thể diễn tả khi đọc mã NON OOP - ngay cả khi nó không - OOP. Và ngay cả khi nó không được thụt lề chính xác (trời ơi!).


3
Có thể có một giải pháp được chôn sâu trong mã này, nhưng gần như không thể tìm ra mọi cách, vì nó không được viết bằng OOP. Nếu bạn biết chính xác nơi phát hiện ngôn ngữ (công cụ trình duyệt) và cách nó lọc các chuỗi gettext, vui lòng cho tôi biết.
kaiser

1
@kaiser - xem chỉnh sửa I cho "công cụ trình duyệt".
krembo99

1
@kaiser .. và xem chỉnh sửa II để biết thêm "nội dung trình duyệt" - và chỉnh sửa III để biết cách kết hợp "nội dung trình duyệt" bên trong "trình duyệt (nội dung)".
krembo99

Ok, tôi đã nâng cấp nó (không phải downvote để hoàn nguyên ở đây), cho nỗ lực của bạn. Ý tưởng sử dụng cookie, là tốt đẹp. Dù sao, đây là một số lưu ý: Chỉnh sửa II sẽ đưa ra lỗi sau require(). Bạn không thể sử dụng define()trên cùng một chuỗi hai lần. Chỉnh sửa III có một số vấn đề với các ngôn ngữ. Chọn en_USsẽ không làm gì (?), Nhưng de_DEsẽ đặt thành English;). Tóm lại: Tôi thưởng tiền thưởng và đưa chúng ra (ví dụ StephenHarris) cho câu trả lời đầy đủ và hiệu quả. Nếu bạn có một cái gì đó tương tự, xin vui lòng cập nhật câu trả lời của bạn (cách tiếp cận cookie thú vị) và tôi có thể thêm và thưởng cho bạn một tiền thưởng.
kaiser

Xin đừng để lại ý kiến ​​cho tôi. Chỉnh sửa câu trả lời của bạn, để mọi người có thể đọc qua ý tưởng của bạn. Phụ chú: IMHO mã bên ngoài nên luôn luôn được thêm vào như Plugin / MU-Plugin / Theme / DROPIN để làm cho nó di chuyển.
kaiser
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.