我们的目标是提供一个按钮/选择下拉菜单或类似按钮,以快速切换公共界面1)语言。

我正在搜索的内容


插件或主题代码...
...或想法
使用load_textdomain()的变通办法将翻译留给.po / .mo文件
关于如何解析的想法不依赖某些textdomain函数时将字符串输入接口(例如ajax / plain php / ini,json,xml文件)


注意:

1 )这不是要用不同的语言发布。

2)我不需要代码来制作实际的下拉菜单/按钮/任何内容。只是关于为UI传递字符串的代码/系统。

谢谢!

评论

如果可以满足页面刷新的需要,则可以重新定义WPLANG常量。我正在两个具有多语言内容的站点上执行此操作,其中多语言插件无法触发UI转换。如果必须是AJAX / JSON解决方案,我将不知道如何提供帮助。

@JohannesPille您切换到哪个位置/钩子?之间:您能否将其移至答案。已经值得投票。谢谢。

我是在插件中完成的,不涉及任何钩子。这是一个非常肮脏的修复程序,我对此并不感到骄傲,但是当时它完成了工作。您可以在此pastebin中看到插件的代码。它的作用是不言自明的。我从中复制此内容的网站使用了WPML的最新免费版本。相当漂亮,请回答。

pastebin URL似乎已死。

@JohannesPille您是否介意将您的代码发布为Q的更新,或添加未过期的粘贴框?

#1 楼

到目前为止,最好的(最简单的)方法是使用区域设置过滤器(在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();


评论


完成表决(也包括所有内联注释)。我们已设置赏金,并会在允许的情况下立即向您授予赏金(还剩23小时-如果我忘记了,请指向我)。

– kaiser
2012年7月6日在11:36

更新以反映该问题的答案。

–斯蒂芬·哈里斯(Stephen Harris)
2012年7月6日上午11:57

N1ce一。已收藏。 +1

–约翰内斯·皮尔(Johannes Pille)
2012年7月6日在16:50

我注意到,仅包含'wp-admin / includes / ms.php'会触发管理员通知以更新您的网络站点(当您是一个站点时!)。可能是需要在自定义函数中复制format_code_lang()。

–斯蒂芬·哈里斯(Stephen Harris)
2012年7月6日在16:54

我添加了一个Gist进行清理-没有时间对其进行测试,因为我目前正在处理插件文件夹,这意味着没有其他插件可以使用。希望您可以使用提供的要点,也可以使用fork / update。我可以在半小时内颁发赏金,但现在必须离开,所以明天再寄给我。感谢您的所有工作-应该在任何默认安装中:)

– kaiser
2012年7月7日,11:15

#2 楼

如果您可以进行页面刷新,则可以重新定义WPLANG常数。我正在两个具有多语言内容的站点上执行此操作,其中多语言插件无法触发UI转换。

评论


嗯..您可以在执行上述代码(在同一ajax请求中),单击按钮或类似操作后,使用ajax替换页面的正文或整个html标签。

–约书亚·阿贝纳泽(Joshua Abenazer)
2011-12-5 19:44



+1。只是看着你的pastebin。这意味着您的设置是http://example.com/language/whatever/,对吗?

– kaiser
2011年12月5日在21:18

@kaiser是的,这是代码来源网站上的设置。如果仅关心UI语言,则应该传递URL查询字符串或设置$ _SESSION变量以在下一次页面加载时触发WPLANG的重新定义。如果您想在多语言站点上复制它,请注意,正如pastebin注释中所述,其中的代码可与WPML(最后一个免费版本)一起使用。无法使用qTranslate将其复制为1到1,因为这些URI不是物理的,而是通过mod_rewrite apache模块重写的。我确定它可以调整,但不能“按原样”工作。

–约翰内斯·皮尔(Johannes Pille)
2011-12-5 22:40

我不会使用qTranslate或WPML。它实际上仅与UI语言有关。广告$ _SESSION)我的问题是afaik很难处理,并且全局变量和数组之间的内容很容易混淆。因此,如果我试图找到一种方法来更改WPLANG,则需要找到一种可靠的方法来将其从一个请求传递到另一个请求。也许add_query_arg / get_query_var可以解决问题...

– kaiser
2011年12月6日,1:19

我只是在考虑这个问题(解决方案仍未内置到项目中):您可以将其包装到一些ajax中吗?我认为这将是解决此问题的最佳方法。我想关闭Q并将其标记为解决方案:)谢谢。

– kaiser
2012年2月4日,下午3:21

#3 楼

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

是您所需要的...

编辑我-发表评论。
首先-谢谢大家谁贡献了下降票的洪流。
(当人们访问不频繁时会发生这种情况:-))

现在-
处理转换的功能在qtranslate中-核心。
(从80行开始或多或少-取决于您想要的版本。)

由于您无法查看NOT OOP代码,因此我现在无事可做-我花了10分钟的时间进行综合,用另一种非OOP代码为您解释非OOp。

(对不起,这里是原始的老家伙)

我已经理解了问题&&假设您希望将代码用于admin &&并假设您将知道如何将其移植到前端,并且&&假设您了解该代码不是最佳的:

<?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分钟内。
我之所以这么说,是因为我这里唯一可用的现成的wordpress安装已经很老了。 (2.9我认为)。

这意味着,由于最近引入了一个新的div结构(带有选项卡),因此语言菜单可能会在上下文帮助div下出现。但它仍然可以正常工作。
(如果有时间,我保证会稍后再讲)

如果我有更多的时间(和一个新的wordpress代码),我可能会将其集成到新的管理栏中使用add_action( 'admin_bar_menu', 'k99_add_language_menu_2', 1000 );(我已经答应过这个问题)

2-您应该将列出的语言文件放在wp-content(更好?)或wp-include中的“ languages”文件夹中。 br />关于这一点-代码只是概念上的证明-当然,如果有更多时间,则应该以动态方式构建菜单,而不是像此处那样。

3-您在配置中的WPLANG应该为空。如果已经设置了某种语言,我不确定它是否可以在更新的wp版本上使用。

4-它是基于qtranslate代码(也是旧版本)的基础上的简单综合和释义的概念证明。 )-因此大多数事情都是以“快速”方式完成的,不一定是“正确”的方式(例如添加JS,没有专用的textdomain等。)。

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


现在-显然最好在组合中添加一些cookie以存储语言。

EDIT III

我答应稍后再讲-这是如何(以一种非常不正确和原始的方式)将其集成到管理栏中(而不是context-help-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 );


只需将此函数(或添加)替换为旧代码(原始NO N-OOP非插件)。

就像我说的那样,我在本地没有admin-bar的新wordpress安装-但它应该可以工作。

(然后再一次,它可能行不通...但是我敢肯定,如果您真的想要,甚至可以认为它不是OOP,也可以解决此问题):-)

立即运行。希望它能对您有所帮助。

编辑IV-将编辑III更改为管理菜单栏的工作版本(至少在我的wp 3.4上如此)

因为我没有3.4的有效安装-现在又返回了,然后我做了-我已经编辑了Edit III解决方案-并且对我有用。

关于投票,我一点也不在乎。而且我不需要任何“奖励”(无论可能是什么。)只是为了练习,您应该将其交给qTranslate的作者。 :-)尽管它不是OOP-它是一个巧妙的插件,在许多领域都有很多值得学习的地方。考虑到此插件发布的“时间”,这甚至是惊人的。值得阅读NON OOP代码(即使不是OOP)也需要付出巨大的努力。即使缩进不正确(天哪!)。

评论


也许在此代码的深度中埋藏着一个解决方案,但由于它不是用OOP编写的,因此几乎不可能解决所有问题。如果您知道语言检测的确切位置(浏览器内容)以及它如何过滤gettext字符串,请告诉我。

– kaiser
2011-12-5 21:24

@kaiser-有关“浏览器内容”的信息,请参见编辑I。

–krembo99
2012年7月8日在9:19



@kaiser ..,请参阅编辑II以获取更多“浏览器内容”-以及编辑III以了解如何将“浏览器内容”合并到“浏览器(内容)”中。

–krembo99
2012年7月8日在9:49

好的,为了您的努力,我对其进行了投票(不是在此处进行投票)。使用cookie的想法很好。无论如何,这里有一些注意事项:Edit II将在require()之后引发错误。您不能在同一字符串上两次使用define()。 Edit III在语言方面存在一些问题。选择en_US不会执行任何操作(?),但是de_DE会将其设置为English;)。总结一下:我奖励悬赏并将其颁发给(例如StephenHarris)以获得完整而可行的答案。如果您有类似的信息,请更新您的答案(有趣的cookie方法),我可能会添加并奖励您。

– kaiser
2012年7月8日上午11:45

请不要对我发表评论。编辑您的答案,以便所有人都可以阅读您的想法。旁注:imho外部代码应始终添加为Plugin / MU-Plugin / Theme / DropIn,以使其可移动。

– kaiser
2012年7月8日在15:40