Hybrid应用,WEB部分的国际化

来源:互联网 发布:cn是哪个国家的域名 编辑:程序博客网 时间:2024/06/08 15:57

我们现在的应用已经有一部分功能Hybrid化了,之前也说过,有客户需要国际版的,我这边需要支持到多语言切换。

当时写了一点代码(http://blog.csdn.net/yeshennet/article/details/53198825),把中文的东西抓出来,给翻译,所以原生部分在哪个时候已经基本解决了。从中文版切换到英文版,只需要到系统设置里面切换下语言就行。虽然还有一点细节,但是这里就不摊开了。

之前翻译一直没出来,所以,web这边的国际化也就一直挂着。

web这边的国际化有几种方案的,原理都是把文字等东西资源化。

第一种:

就像msdn上的做法一样



原理应该是通过路由来定位给到对应的网页

Global.asax.cspublic static void RegisterRoutes(RouteCollection routes){routes.IgnoreRoute("{resource}.axd/{*pathInfo}");routes.MapRoute("Globalization", // 路由名称"{lang}/{controller}/{action}/{id}", // 带有参数的 URLnew { lang = "zh", controller = "Home", action = "Index", id = UrlParameter.Optional }, // 参数默认值new { lang = "^[a-zA-Z]{2}(-[a-zA-Z]{2})?$" }    //参数约束);routes.MapRoute("Default", // 路由名称"{controller}/{action}/{id}", // 带有参数的 URLnew { controller = "Home", action = "Index", id = UrlParameter.Optional } // 参数默认值);}

(代码来自:http://www.tuicool.com/articles/bmIbe2)

这种的好处是,可以有针对性的给页面,官方也是这样用的。不过问题可能就是出在会改变链接上,加了一个前缀,所以之前代码中写了不少绝对路径,例如(/Order/Index)都要改一轮,原生那边也要跟着改一轮,切换语言时也要手动改一轮。


第二种:

通过Accept-Language的第一个语言来确定系统当前优先使用的语言

private string innerGetFirstAcceptLanguageInRequest() {    string language = "zh-CN";    if (enbaleAutoSwitchLanguage && Request.UserLanguages != null)    {        string[] array = Request.UserLanguages;//eg : Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4        if (array.Length > 0)        {            string firstLanguage = array[0];            if (!string.IsNullOrWhiteSpace(firstLanguage))            {                if (!firstLanguage.StartsWith("zh"))                {                    //firstLanguage : zh  zh-cn zh-Hans zh-Hans-CN zh-tw                    //only support "zh-CN" and "en-US" currently                    language = "en-US";                }            }        }    }    return language;}

(参考资料:http://www.cnblogs.com/haogj/p/3921756.html)

Accept-Language第一个值 在Chrome中可以这样设置





在手机中就是系统语言了。


然后在把获取到的语言信息同步到cookie、C#中

private void innerUpdateCulture(string language){    //cache lang in cookie,we may use it in js    if (Request.Cookies != null)    {        if (Request.Cookies[cacheCookieName] != null)        {            HttpCookie lanCookie = Request.Cookies[cacheCookieName];            lanCookie[cacheCookieKey] = language;        }        else        {            HttpCookie lanCookie = new HttpCookie(cacheCookieName);            lanCookie[cacheCookieKey] = language;            Response.Cookies.Add(lanCookie);        }    }    //update culture in C#    if (!string.IsNullOrEmpty(language))    {        Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);        Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(language);    }}

(参考资料:http://www.huhailong.cn/article_10.html)


然后C#上的资源就自动转过去了,js上如果需要国际化的信息,就可以从cookie中拿

Tools.isChinese = function() {     var arr,reg=new RegExp("(^| )"+"LdLang"+"=([^;]*)(;|$)");    if(arr=document.cookie.match(reg)){        var str = unescape(arr[2]);         var array = str.split("; ");         for(var i=0;i<array.length;i++){             var arr=array[i].split("=");             if("lan"==arr[0]){                return arr[1] == "zh-CN";            }        }     }    return true;};

会写得这么细致,是因为我用的是第二种。

好处就是原生系统切换语言的时候,web上的东西不用做什么处理(基本不用),就能把语言切换过去。地址也不用动(之前有写会跨几个不同版本的那些集团版也不用再来回搞一波)。当然原生那边也不是什么都不用做,它要确保Accept-Language中的值是对的。

接下来就是适配页面了,基本上都是体力活了。


代码都弄进系统了,所以不打算给demo了。这里给下step by step吧 :)

step1、选中项目右键-->“添加”-->“添加ASP.NET文件夹”-->“App_GlobalResources”  选中“App_GlobalResources”右键添加一个资源文件Global.resx

在新建中文和英文的资源:

例如:


这里的命名格式要保持,就是**.en-US.resx   **.zh-CN.resx

可以这样使用,举这个例子是为了说明,字符串中的东西,不要用拼接的方式去做,C#中提供了很方便的string.Format。

以前拼接了怎么办?这是债,要还  :  )

step2、在controller中新建一个BaseController

using System;using System.Collections.Generic;using System.Configuration;using System.Linq;using System.Web;using System.Web.Mvc;using System.Threading;namespace MobileWeb.Controllers{    /// <summary>    /// Refer to:    /// http://www.huhailong.cn/article_10.html    /// http://www.cnblogs.com/haogj/p/3921756.html    ///     /// by Yeshen    /// 2016.12.13    /// </summary>    public class BaseController : Controller    {        //config.js "Tools.isChinese()" quto this two key        private const string cacheCookieName = "LdLang";        private const string cacheCookieKey = "lan";        //enbaleAutoSwitchLanguage default value is "true"        //if disable , set this value to "false";        private const bool enbaleAutoSwitchLanguage = true;        /*         * if any need?        protected void OnlyEnglish() {            this.innerUpdateLanguage("en-US");        }        */        protected void Internationalization()        {            string language = innerGetFirstAcceptLanguageInRequest();            this.innerUpdateCulture(language);        }        /////////////inner////////////////////////        private string innerGetFirstAcceptLanguageInRequest() {            string language = "zh-CN";            if (enbaleAutoSwitchLanguage && Request.UserLanguages != null)            {                string[] array = Request.UserLanguages;//eg : Accept-Language:zh-CN,zh;q=0.8,en-US;q=0.6,en;q=0.4                if (array.Length > 0)                {                    string firstLanguage = array[0];                    if (!string.IsNullOrWhiteSpace(firstLanguage))                    {                        if (!firstLanguage.StartsWith("zh"))                        {                            //firstLanguage : zh  zh-cn zh-Hans zh-Hans-CN zh-tw                            //only support "zh-CN" and "en-US" currently                            language = "en-US";                        }                    }                }            }            return language;        }        private void innerUpdateCulture(string language)        {            //cache lang in cookie,we may use it in js            if (Request.Cookies != null)            {                if (Request.Cookies[cacheCookieName] != null)                {                    HttpCookie lanCookie = Request.Cookies[cacheCookieName];                    lanCookie[cacheCookieKey] = language;                }                else                {                    HttpCookie lanCookie = new HttpCookie(cacheCookieName);                    lanCookie[cacheCookieKey] = language;                    Response.Cookies.Add(lanCookie);                }            }            //update culture in C#            if (!string.IsNullOrEmpty(language))            {                Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo(language);                Thread.CurrentThread.CurrentCulture = System.Globalization.CultureInfo.CreateSpecificCulture(language);            }        }    }}

然后全部的controller都要继承它,每个方法都要调用Internationalization,例如


step3、找出项目中的全部中文字符,资源化它。

厚脸皮的说,我年初开始写web的时候,虽然web是新手,但是原生那边有一些经验,所以一开始上来都是直接用资源、用string.format去写,所以这一步反而没什么工作量。

如果需要找出来,可以参考我这篇博客(http://blog.csdn.net/yeshennet/article/details/53198825)

step4、页面细节调整。

替换过后,每个页面都要看看,真会页面错乱,文字溢出的。


中午吃饭的时候,我们几个小伙伴的讨论这个,PC端的小伙伴有个意见:这里应该保留一个配置,如果一定要指定中文版或者英文版,要给指定到。

我虽然是拒绝的,因为现在产品SAAS化,不可能在针对某个酒店给配置了。然而考虑到我就要离职了,不要给接手的小伙伴造成困扰,我还是留了配置。

在BaseController中,关掉 enbaleAutoSwitchLanguage 选项,或者

/* * if any need?protected void OnlyEnglish() {this.innerUpdateLanguage("en-US");}*/

然后今天的大部分时间都在弄step3、step4,东西不少,翻译那边也要协助搞,必然是耗时的。


转载请保留地址:http://blog.csdn.net/yeshennet/article/details/53614156

by Yeshen 2016.12.13



0 0