国际化是做跨境站点经常会碰到的需求, 下面就nodejs中如何实现国际化进行整理
依赖环境与包
- nodeJS 5.5+
- express 4+
- i18n 0.8+
国际化实现原理
简单的说, 国际化是在服务端请求处判断客户端的默认语言版本, 然后服务端渲染时切换不同的语言(注: 国际化只适合静态内容, 动态内容如数据库中的数据并不适应于国际化)
实现步骤
-
npm install i18n –save 安装i18n包github
-
在nodejs项目根目录创建locales目录, 目录下可以放置不同语言的文字定义文件, 默认.json 例如:zh-CN.json示例
{ "loginTitle": "'会员登录|跨境供应链", "forgetPwdTitle": "找回密码|跨境供应链", "loginSubTitle": "会员登录" ... }
zh-TW.json示例
{ "loginTitle": "'會員登錄|跨境供應鏈", "forgetPwdTitle": "找回密碼|跨境供應鏈", "loginSubTitle": "會員登錄" ... }
-
nodejs的入口文件app.js(或是其他名字)里加入如下配置
var express = require('express'); var i18n = require('i18n'); var app = express(); ... //添加setLocale中间件,注意必须在配置session之后 app.use(setLocale); var languages = ['zh-CN', 'zh-TW']; // 定义setLocale中间件 function setLocale(req, res, next){ var locale; //配置i18n i18n.configure({ locales: languages, //声明包含的语言 register: res, directory: __dirname + '/locales', //翻译json文件的路径 defaultLocale: 'zh-CN', //默认的语言,即为上述标准4 indent: "\t", //extension: '.js' // 由于 JSON 不允许注释,所以用 js 会方便一点,也可以写成其他的,不过文件格式是 JSON }); //客户端可以通过修改cookie进行语言切换控制 if(req.cookies['locale']){ locale = req.cookies['locale']; } else if(req.acceptsLanguages()){ locale = req.acceptsLanguages()[0]; } if(!~languages.indexOf(locale)) { locale = 'zh-CN'; } // 设置i18n对这个请求所使用的语言 res.setLocale(locale); next(); };
-
在路由router里输出国际化文字
var express = require('express'); var router = express.Router(); ... //跳转登录页 router.get('/login',function(req, res, next){ //1) @todo 少获取logo图接口 需要获取后传值给view //2) @todo 少获取登录界面背景图接口 需要获取后传值给view res.render('login/login', { title: res.__('loginTitle'), layout: 'layouts/layout_login', systemTime: Date.now(), errorMsg: req.cookies.errorMsg }); });
-
在ejs模板里输出国际化文字
<form id="J-login-form" method="post" action="/login" novalidate="novalidate"> <div class="form-title "> <p class="title"><%=__('loginSubTitle')%></p> <div class="alert alert-danger alert-dismissible display-hide" role="alert"> <i class="iconfont icon-del-error"></i> <span class="alert-text"><%=__('loginAlertText')%></span> </div> </div> <div class="form-group form-group-lg"> <span class="iconfont icon-head"></span> <label for="username" class="hidden"><%=__('loginUserLabel')%></label> <input id="username" name="username" type="text" maxlength="32" class="form-control txt-show" placeholder="<%=__('loginUserLabel')%>" value="" autocomplete="off"/> <span class="close-wrapper"> <button type="button" class="J-close-btn close display-hide" aria-label="Close"> <span aria-hidden="true">×</span> </button> </span> </div> </form>