JS魔法堂:不完全国际化&本地化手册 之 理論篇
前言
最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。
本篇将阐述国际化和本地化的概念,以及其中一个很重要的概念——Language tag(也叫Language code 或 Culture)。
何为国际化?
国际化我认为就是应用支持多语言和文化习俗(数字、货币、日期和字符比较算法等),而本地化则是应用能识别用户所属文化习俗自动适配至相应的语言文化版本。
过去常常以为国际化就是字符串的替换——如"你好!"替换为"What's up, man!",其实具体是分为以下5方面:
- 字符串替换
如"你好!"
替换为"What's up, man!"
. - 数字表示方式
如1200.01
,英语表示方式为1,200.01
,而法语则为1 200,01
,德语则为1.200,01
. - 货币表示方式
如人民币¥1,200.01
,美元表示方式为$1,200.01
,而英语的欧元则为€1,200.01
,德语的欧元则为1.200,01 €
.
注意: 这里没有还没算上汇率呢. - 日期表示方式
如2016年9月15日
,英语表示方式为9/15/2016
, 而法语为15/9/2016
, 德语为15.9.2016
. - 字符比较算法
如ä
和z
比较时,英语、德语中均是ä
排在z
前面,而在瑞典语中则是z
排在ä
前面.
本地化的关键 —— Language Tag
既然要自动适配至用户所属的语言文化版本,那么总得有个根据才能识别吧?我想大家应该对zh-CN
和en
等不陌生吧,而它们正是我们所需的根据了!在我们使用已有i18n库实现国际化/本地化时,必定会写下以下文档
{
"en": { "name": "Enter Name" },
"zh-CN": { "name": "输入姓名" }
}
但除了en
和zh-CN
还有其他键吗?它们的组成规则又是如何的呢?下面我们来稍微深入的了解这些Language Tag吧!
语法规则
注意以下采用ABNF语言描述(ABNF的语法请参考语法规范:BNF与ABNF)
Language-Tag = langtag
/ privateuse
/ grandfathered
langtag = language
["-" script]
["-" region]
*("-" variant)
*("-" extension)
["-" privateuse]
可以看到Language-Tag
分为langtag
,privateuse
和 grandfatherd
三个子类,下面我们先了解一般情况用不上的两个吧!
privateuse
标签的意思不由subtag registry定义,而是由使用的团队间私自定义、维护和使用。
格式:
privateuse = "x" 1*("-" (1*8alphanum))
示例:x-zh-CN
是privateuse,其意思不一定与languagezh-CN
一致。
注意: 只作为小集团内部用可以,决不能大范围适用。
grandfathered
用于向后兼容。由于RFC 4646前的标签无法完全匹配当前registry的标签语法和意思,因此通过grandfathered来提供向后兼容的特性。
语法:
grandfathered = irregular
/ regualr
irregular = "en-GB-oed" ; irregular tags do not match
/ "i-ami" ; the 'langtag' production and
/ "i-bnn" ; would not otherwise be
/ "i-default" ; considered 'well-formed'
/ "i-enochian" ; These tags are all valid,
/ "i-hak" ; but most are deprecated
/ "i-klingon" ; in favor of more modern
/ "i-lux" ; subtags or subtag
/ "i-mingo"
/ "i-navajo"
/ "i-pwn"
/ "i-tao"
/ "i-tay"
/ "i-tsu"
/ "sgn-BE-FR"
/ "sgn-BE-NL"
/ "sgn-CH-DE"
regular = "art-lojban" ; these tags match the 'langtag'
/ "cel-gaulish" ; production, but their subtags
/ "no-bok" ; are not extended language
/ "no-nyn" ; or variant subtags: their meaning
/ "zh-guoyu" ; is defined by their registration
/ "zh-hakka" ; and all of these are deprecated
/ "zh-min" ; in favor of a more modern
/ "zh-min-nan" ; subtag or sequence of subtags
/ "zh-xiang"
注意: 几乎所有grandfarthered标签均可被当前registry的标签及其组合作替代(像i-tao
可以被tao
代替),因此如无意外请使用现行的标签吧。
下面就到了我们的重头戏langtag了,首先我们看看langtag下的第一个subtag——language.
Primary language subtag
像en
这种就是Primary language subtag,用于标识资源所对应的语言。
语法:
language = 2*3ALPAH
["-" extlang]
/ 4ALPHA
/ 5*8ALPHA
extlang = 3ALPHA
*2("-" 3ALPHA)
看到language有三种形式,其中让我比较好奇的是第一种2*3ALPHA ["-" extlang]
。这种形式中前面的2*3ALPHA
称为macrolanguage,用于标明资源对应一种语言的汇总,而具体的某一种语言/方言则通过extlang指定。而包含extlang部分的language也被称为encompassed language.
如zh-cmn
和zh-yue
就是encompassed language,其中zh
是macrolanguage,而cmn
和yue
则是extlang。
这里有个很有趣的事情是,我们认为普通话和广东话等都是汉语的方言,但西方却认为普通话、广东话根本就不属于一种语言,因此像zh-cmn
和zh-yue
在规范中被设置为redundant,建议直接使用cmn
和yue
等。不过由于历史原因,我们还是使用zh-CN
代表cmn-CN
。
另外现在可以作为macrolanguage的就只有7个标签(ar
,kok
,ms
,sw
,uz
,zh
和sgn
)
另外几个和cmn类似的subtags如下
cmn 普通话(官话、国语)
wuu 吴语(江浙话、上海话)
czh 徽语(徽州话、严州话、吴语-徽严片)
hak 客家语
yue 粤语(广东话)
nan 闽南语(福建话、台语)
cpx 莆仙话(莆田话、兴化语)
cdo 闽东语
mnp 闽北语
zco 闽中语
gan 赣语(江西话)
hsn 湘语(湖南话)
cjy 晋语(山西话、陕北话)
注意: 一般采用全小写
Script subtag
用于指定字迹或文字系统资源所属的语言和方言等。
语法:
script = 4ALPHA
注意: 一般采用首字母大写,后续字母全小写
Region subtag
指定与国家、地域对应的语言/方言文化。
语法:
region = 2ALPHA
/ 3DIGIT
注意: 一般采用全大写
Variant subtag
指定其他subtag又无法提供的额外信息
语法:
variant = 5*8alphanum
/ (DIGIT 3alphanum)
示例:de-CH-1996
其中1996是variant subtag,整体意思是在Switzerland使用的自1996改良过的德语。
Extension subtag
提供一种机制让我们去扩展langtag
语法:
extension = singleton 1*("-" (2*8alphanum))
singleton = DIGIT
/ %x41-57
/ %x59-5A
/ %x61-77
/ %x79-7A
现在仅支持u
作为sigleton的值。
示例:de-DE-u-co-phonebk
表示采用电话本核对的方式对内容进行排序等操作。
更多关于language-tag的信息请参考BCP 47
如何选择Language Tag
硬着头皮啃下这么多规范的内容,但我还不知道如何组合合适的language-tag呢:(其实选择和组合的原则就只有一条
在足以区别当前上下文中其他language-tag的前提下,保持language-tag足够地短小精干
示例1:下文普通话、粤语并存
<p lang="cmn">
小陈说:"老大爷,东方广场怎么走啊?"
老大爷回答道:"<span lang="yue">你讲咩也啊?我听唔明喔。</span>"
</p>
示例2:下文含大陆人讲英语、香港人讲普通话和美国人说英语
<p lang="cmn">
小陈说:"<span lang="en-CN">Hi, where are you come from?</span>"
李先生说:"<span lang="cmn-HK">你的英文跟我的普通话一样普通啊,哈哈!</span>"
Simon说:"<span lang="en">Hey, what's up!</span>"
</p>
那现在引出另一个问题,那就是我们怎么知道各个subtag具体定义了哪些值呢?
具体都定义在IANA Language Subtag Registry中了。
假如觉得查找起来还是不方便,那么就使用Language Subtag Lookup tool吧!
另外若不清楚各国各地区所使用的语言或方言时,可通过Ethnologue查看,直接点击地图上的区域即可获取相应的subtag信息。
总结
现在我们已经对国际化和本地化有了更全面的理解,也对Language tag有了更深入的认识,现在是不是迫不及待想挽起袖子撸代码呢?敬请期待下篇《JS魔法堂:不完全国际化&本地化手册 之 实战篇》
尊重原创,转载请注明来自: http://www.cnblogs.com/fsjohnhuang/p/5908028.html _肥仔John
感谢
网页头部的声明应该是用 lang="zh" 还是 lang="zh-cn"?
Language Subtag Registry
BCP 47
Language on the Web
Choosing a Language Tag
Language tags in HTML and XML
JS魔法堂:不完全国际化&本地化手册 之 理論篇的更多相关文章
- JS魔法堂:不完全国际化&本地化手册 之 实战篇
前言 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...
- JS魔法堂:不完全国际化&本地化手册 之 拓展篇
前言 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求--国际化&本地化.熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已. ...
- JS魔法堂:判断节点位置关系
一.前言 在polyfill querySelectorAll 和写弹出窗时都需要判断两个节点间的位置关系,通过jQuery我们可以轻松搞定,但原生JS呢?下面我将整理各种判断方法,以供日后查阅. 二 ...
- JS魔法堂:LINK元素深入详解
一.前言 我们一般使用方式为 <link type="text/css" rel="stylesheet" href="text.css&quo ...
- JS魔法堂:IMG元素加载行为详解
一.前言 在<JS魔法堂:jsDeferred源码剖析>中我们了解到img元素加载失败可以作为函数异步执行的优化方案,本文打算对img元素的加载行为进行更深入的探讨. 二.资源加载的相关属 ...
- JS魔法堂:jsDeferred源码剖析
一.前言 最近在研究Promises/A+规范及实现,而Promise/A+规范的制定则很大程度地参考了由日本geek cho45发起的jsDeferred项目(<JavaScript框架设计& ...
- JS魔法堂:属性、特性,傻傻分不清楚
一.前言 或许你和我一样都曾经被下面的代码所困扰 var el = document.getElementById('dummy'); el.hello = "test"; con ...
- JS魔法堂:那些困扰你的DOM集合类型
一.前言 大家先看看下面的js,猜猜结果会怎样吧! 可选答案: ①. 获取id属性值为id的节点元素 ②. 抛namedItem is undefined的异常 var nodes = documen ...
- JS魔法堂:doctype我们应该了解的基础知识
一.前言 什么是doctype?其实我们一直使用,却很少停下来看清楚它到底是什么,对网页有什么作用.本篇将和大家一起探讨那个默默无闻的doctype吧! 二.什么是doctype doctype或DT ...
随机推荐
- 关于DOM的操作以及性能优化问题-重绘重排
写在前面: 大家都知道DOM的操作很昂贵. 然后贵在什么地方呢? 一.访问DOM元素 二.修改DOM引起的重绘重排 一.访问DOM 像书上的比喻:把DOM和JavaScript(这里指ECMScri ...
- 快速构建H5单页面切换骨架
在Web App和Hybrid App横行的时代,为了拥有更好的用户体验,单页面应用顺势而生,单页面应用简称`SPA`,即Single Page Application,就是只有一个HTML页面的应用 ...
- Web性能优化:What? Why? How?
为什么要提升web性能? Web性能黄金准则:只有10%~20%的最终用户响应时间花在了下载html文档上,其余的80%~90%时间花在了下载页面组件上. web性能对于用户体验有及其重要的影响,根据 ...
- 谈一下关于CQRS架构如何实现高性能
CQRS架构简介 前不久,看到博客园一位园友写了一篇文章,其中的观点是,要想高性能,需要尽量:避开网络开销(IO),避开海量数据,避开资源争夺.对于这3点,我觉得很有道理.所以也想谈一下,CQRS架构 ...
- 微信小程序体验(2):驴妈妈景区门票即买即游
驴妈妈因为出色的运营能力,被腾讯选为首批小程序内测单位.驴妈妈的技术开发团队在很短的时间内完成了开发任务,并积极参与到张小龙团队的内测问题反馈.驴妈妈认为,移动互联网时代,微信是巨大的流量入口,也是旅 ...
- AFNetworking 3.0 源码解读(八)之 AFImageDownloader
AFImageDownloader 这个类对写DownloadManager有很大的借鉴意义.在平时的开发中,当我们使用UIImageView加载一个网络上的图片时,其原理就是把图片下载下来,然后再赋 ...
- bcp 命令实例
set sql_flow="select Id,',',ApplierName,',',FlowStatus,',',IsApproved,',',CreateTime from *** w ...
- Loadrunner Http Json接口压力测试
前天接到了一个测试任务,要求测试一下ES(elsticsearch)在不同并发下的查询效率.如图: 业务场景是在客户端根据具体车牌查询相关车辆信息,结果返回前10条记录. 从图中可以看到,接口的请求参 ...
- JAVA FreeMarker工具类
FreeMarkerUtil.java package pers.kangxu.datautils.utils; import java.io.File; import java.io.StringW ...
- Tomcat常见问题及常用命令
很长时间不用tomcat好多命令都忘记了,所以准备自己记录下来,以便参考.刚好也希望可以开始养成记博客的好习惯. 1.查看java的版本号 进入java的安装目录后,使用命令:java -versio ...