버튼을 클릭하여 언어 변경


21

목표는 공용 인터페이스 1) 언어를 즉시 전환 할 수있는 버튼 / 선택 드롭 다운 또는 이와 유사한 기능을 제공하는 것입니다 .

내가 찾고있는 것

  • 플러그인 또는 테마 코드 ...
  • ... 또는 아이디어
  • 와 함께 해결 방법을 사용하면 load_textdomain().po / .mo 파일로 변환하는 것이 좋습니다.
  • 일부 textdomain 함수에 의존하지 않을 때 문자열을 인터페이스 (예 : ajax / plain php / ini, json, xml 파일)로 구문 분석하는 방법에 대한 아이디어

노트 :

1) 다른 언어로 출판하는 것이 아닙니다.

2) 실제 드롭 다운 / 버튼 / 무엇이든 만들기 위해 코드가 필요하지 않습니다. UI에 문자열을 제공하는 코드 / 시스템에 관한 것입니다.

감사!


1
페이지를 새로 고치려면 WPLANG상수를 재정의하는 것이 옵션 일 수 있습니다. 다국어 플러그인이 UI 번역을 트리거하지 못하는 다국어 콘텐츠가있는 두 사이트 에서이 작업을 수행하고 있습니다. 그것이 AJAX / JSON 솔루션이어야한다면, 나는 도울 수있는 방법을 모른다.
Johannes Pille

@JohannesPille 어느 시점 / 후크로 전환합니까? Btw : 답변으로 옮길 수 있습니까? 이미 투표 할 가치가 있습니다. 감사.
카이저

나는 플러그인에서 그것을하고있다. 그것은 꽤 더러운 수정이며 나는 그것을 자랑스럽게 생각하지는 않지만 그 당시에는 일을 마쳤습니다. 이 pastebin 에서 플러그인 코드를 볼 수 있습니다 . 그것이하는 것은 자기 설명이다. 이 사이트를 복사 한 사이트는 마지막 무료 버전의 WPML을 사용합니다. 공정한 enuff, 대답으로 옮겼습니다.
Johannes Pille

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
이 질문에 대한 답변을 반영하여 업데이트되었습니다 .
Stephen Harris

N1ce 하나. 북마크. +1
Johannes Pille

포함 'wp-admin/includes/ms.php'하면 네트워크 사이트 업데이트에 대한 관리자 알림이 트리거됩니다 (단일 사이트 인 경우). format_code_lang()사용자 정의 함수 내에서 복제해야 할 수도 있습니다 .
Stephen Harris

내 정리와 함께 요점을 추가했습니다 -현재 플러그인 폴더로 엉망이되어 테스트 할 시간이 없었으므로 다른 플러그인이 작동하지 않습니다. 제공된 요지 및 포크 / 업데이트로 작업 할 수 있기를 바랍니다. 30 분 안에 현상금을 수여 할 수 있지만 지금 떠나야하므로 내일 보내겠습니다. 모든 작업에 감사드립니다-모든 기본 설치에 있어야합니다 :)
kaiser

5

페이지를 새로 고치려면 WPLANG상수를 재정의하는 것이 옵션 일 수 있습니다. 다국어 플러그인이 UI 번역을 트리거하지 못하는 다국어 콘텐츠가있는 두 사이트 에서이 작업을 수행하고 있습니다.


흠 .. 당신은 위의 코드를 실행 한 후 (같은 아약스 요청에서) 버튼을 클릭하거나 그와 비슷한 것을 수행하여 ajax를 사용하여 해당 문제에 대한 페이지의 본문 또는 전체 html 태그를 대체 할 수 있습니다.
Joshua Abenazer

+1. 당신의 pastebin을 보았습니다. 즉, 설정이입니다 http://example.com/language/whatever/.
카이저

@kaiser Yup, 이것이 코드가 나오는 사이트의 설정입니다. UI 언어에만 관심이있는 경우 URL 쿼리 문자열을 전달하거나 다음 페이지로드시 $_SESSION재정의를 트리거하도록 변수를 설정 WPLANG해야합니다. 다국어 사이트에서 이것을 복제해야한다면, pastebin에 대한 주석에서 알 수 있듯이이 코드는 마지막 무료 버전 인 WPML에서 작동합니다. 이러한 URI는 물리적이지 않지만 mod_rewrite아파치 모듈을 통해 다시 작성되므로 qTranslate를 사용하여 1에서 1로 복제 할 수 없습니다 . 조정할 수는 있지만 "있는 그대로"작동하지 않습니다.
Johannes Pille

qTranslate 또는 WPML을 사용하지 않습니다. 정말 UI 언어에 관한 것입니다. Ad $_SESSION) 내 문제는 afaik이 다루기가 매우 어렵고 전역과 배열 사이의 물건이 쉽게 섞일 수 있다는 것입니다. 따라서 변경 방법 WPLANG을 찾으려면 한 요청에서 다른 요청으로 전달할 수있는 확실한 방법을 찾아야합니다. 아마도 add_query_arg/get_query_var트릭을 할 것입니다 ...
kaiser

방금 이것에 대해 다시 생각하고있었습니다 (아직 솔루션이 프로젝트에 내장되어 있지 않습니다) : 이것을 아약스로 감쌀 수 있습니까? 나는 이것이 이것을 해결하는 가장 좋은 방법이라고 생각합니다. Q를 닫고 솔루션으로 표시하고 싶습니다 :) 감사합니다.
kaiser February

2

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

필요한 것입니다 ...

의견 후- 편집 . 첫 번째-downvotes 급류에 기여한 모든 분들께 감사드립니다. (이것은 자주 방문하지 않을 때 발생하는 일입니다 :-))

now-스위치를 처리하는 기능은 qtranslate-core입니다. (80 행 이하에서 시작합니다. 원하는 버전에 따라 다릅니다.)

NOT OOP 코드를 조사 할 수없고, 이제는 할 일이 없습니다. 합성하는 데 10 분이 걸렸습니다.

(죄송합니다-여기에 오래된 오래된 스쿨)

내가 질문을 이해했다고 가정하면 & & 당신이 관리자를위한 코드가되기를 원한다고 가정하면 & & 당신이 원한다면 & & 코드가 최적이 아니라는 것을 이해한다고 가정하면 코드를 프론트 엔드로 포팅하는 방법을 알 것이라고 가정합니다.

<?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 (더 나은 ??) 또는 wp-include의 "languages"폴더 내에 나열된 언어 파일이 있어야합니다. 이 점과 관련하여-코드는 개념에 대한 증거 일뿐입니다. 물론 시간이 더 많은 경우 메뉴는 동적 방식으로 작성되어야하며 여기서는 수행하지 않아야합니다.

3-구성의 WPLANG이 비어 있어야합니다. 언어가 이미 설정된 경우 최신 wp 버전에서 작동하는지 확실하지 않습니다.

4-qtranslate 코드 (이전 버전)에서 볼 수있는 것을 기반으로하는 단순하게 합성되고 변형 된 개념 증명입니다. 따라서 대부분의 작업은 반드시 "올바른"방법이 아니라 "빠른"방법으로 수행됩니다 (JS 추가 등). 전용 텍스트 도메인 등이 없습니다.).

편집 II

누군가 오늘 운이 좋다! (비행 지연 )

접근 방식에 대한 "아이디어"를 찾고 있었기 때문에 여기 또 다른 유명한 것이 있습니다.

플러그인이나 다른 비 독점 환경에는 맞지 않지만 "브라우저 항목"을 처리하는 방법에 대한 다른 방향을 제시 할 수 있습니다.

이것은 하나 같은 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', '');
        }
    }
 }

이제 wp-config에서 WPLANG 상수 바로 앞에 코드를 포함시켜야합니다.

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

이제 분명히 언어를 저장하기 위해 쿠키를 믹스에 추가하는 것이 좋습니다.

편집 III

나는 이것으로 나중에 다시 돌아가겠다고 약속했다-여기에 (매우 정확하고 원시적 인 방법으로) 어떻게 상황에 맞는 도움말 메뉴 대신 관리 막대 안에 통합 될 수 있는지가 있습니다.

 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가 아니라는 사실에도 불구하고 많은 영역에서 배울 것이 많은 독창적 인 플러그인입니다. 이 플러그인 릴리즈의 "언제"를 고려하면 놀랍습니다. NOP가 아닌 경우에도 NON OOP 코드를 읽는 데있어 불가피한 노력의 가치 그리고 올바르게 들여 쓰기되지 않더라도 (좋은 신!).


3
이 코드의 깊이에 솔루션이 묻혀있을 수도 있지만 OOP로 작성되지 않았기 때문에 모든 방법을 알아내는 것이 거의 불가능합니다. 정확한 언어 감지 위치 (브라우저 항목)와 gettext 문자열을 필터링하는 방법을 알고 있다면 알려주십시오.
카이저

1
@kaiser- "브라우저 항목"편집 I 참조.
krembo99

1
@kaiser .. 및 더 많은 "브라우저 항목"에 대해서는 편집 II를 참조하십시오. "브라우저 항목"에 "브라우저 항목"을 통합하는 방법에 대해서는 III을 편집하십시오
krembo99

좋아, 나는 당신의 노력을 위해 그것을 upvoted (여기서 되돌리기 위해 downvote하지 않음). 쿠키를 사용하는 아이디어는 좋습니다. 어쨌든, 여기 몇 가지 참고 사항이 있습니다 : Edit II는 require(). define()같은 문자열에서 두 번 사용할 수 없습니다 . 편집 III에는 언어에 문제가 있습니다. 선택하면 en_US아무것도하지 않지만 (?)로 de_DE설정됩니다 English. 요약하자면, 나는 바운티를 수여하고 (예를 들어 StephenHarris) 완전하고 효과적인 답변을 제공합니다. 당신이 그런 것을 얻었다면, 당신의 답변을 업데이트하십시오 (쿠키 접근 흥미로운) 그리고 나는 당신에게 현상금을 추가하고 보상 할 수 있습니다.
카이저

저에게 의견을 남기지 마십시오. 모든 사람이 아이디어를 읽을 수 있도록 답변을 수정하십시오. 참고 사항 : imho 외부 코드는 항상 Plugin / MU-Plugin / Theme / DropIn으로 추가하여 이동할 수 있도록해야합니다.
카이저
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.