在开发多语言网站时,常常需要将JavaScript字符串本地化。传统的方法包括将资源存储在单独的文件中或在字典中存储翻译后的字符串。但是这些方法并不完美,因为它们需要在客户端浏览器中存储所有翻译后的字符串,即使用户只需要一种语言。此外,这些方法通常需要通过特殊变量引用翻译后的字符串,例如:
project.translation.testMessage['it-IT']
认为用户只需要在客户端JavaScript文件中获得他们自己的语言字符串,并且更喜欢在JavaScript代码中使用如下形式的字符串:
@Cult.Text("ID")
创建了一个名为JsController.cs
的控制器:
public class JsController : Controller
{
// 记得在这里管理缓存
public JavaScriptResult Index(string js, string lang, string ver)
{
Response.ContentType = "text/javascript";
var script = RenderRazorViewToString(js, null);
var jsRet = new JavaScriptResult();
script = script.Replace("", string.Empty);
var javaScriptMinifier = MinifierFactory.Get();
string minifiedJavaScript = javaScriptMinifier.Minify(script);
jsRet.Script = minifiedJavaScript;
return jsRet;
}
private string RenderRazorViewToString(string viewName, object model)
{
ViewData.Model = model;
using (var sw = new StringWriter())
{
var viewResult = ViewEngines.Engines.FindPartialView(ControllerContext, viewName);
var viewContext = new ViewContext(ControllerContext, viewResult.View, ViewData, TempData, sw);
viewResult.View.Render(viewContext, sw);
viewResult.ViewEngine.ReleaseView(ControllerContext, viewResult.View);
return sw.GetStringBuilder().ToString();
}
}
}
然后在视图文件夹中,创建了一个名为test.js.cshtml
的视图。在这个视图中,可以使用Razor引擎的强大功能来生成JavaScript库(为什么不呢??)也可以为不同的库创建单独的文件,并在添加<script></script>
标签时使用智能感知,这些标签在渲染视图时会被移除。
这个视图也会被SquishIt
压缩:
@{
Layout = "";
}
<script type="text/javascript">
// 使用这行代码来获取智能感知...
function Test() {
alert("@Cult.Text("TEST")");
return false;
};
</script>
在_Layout.cshtml
中,通过调用控制器来引用脚本(传递当前语言和版本,仅用于管理缓存客户端文件):
<script src="/Js?js=test.js⟨=@Cult.CurrentCulture()&ver=1.4" type="text/javascript"></script>
使用这个很棒的解决方案将当前用户文化存储在cookie中,并在服务器端获取它:
使用HttpModule进行本地化是否安全?
创建了一个名为Cult
的类来管理翻译系统,这是一个简单的实现,可以使用资源或其他系统来翻译字符串:
public static class Cult
{
public static string CurrentCulture()
{
return System.Threading.Thread.CurrentThread.CurrentCulture.Name.Substring(0, 2).ToLower();
}
public static string Text(string messageID)
{
// 这是一个假的翻译库实现,但可以使用数据库或资源...
var currentCulture = System.Threading.Thread.CurrentThread.CurrentCulture.Name.Substring(0, 2).ToLower();
var defaultMessage = string.Empty;
if (messageID == "TEST")
return currentCulture == "it" ? "Testo di prova in Italiano" : "Text message in English";
return currentCulture == "it" ? "Clicca qui per effettuare il test di localizzazione" : "Click here to test the localization";
}
}
就是这样!创建了一个系统,允许管理外部JavaScript文件,并在其上使用本地化。