首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >JS魔法堂:不完全国际化&本地化手册 之 理論篇

JS魔法堂:不完全国际化&本地化手册 之 理論篇

作者头像
^_^肥仔John
发布于 2018-01-18 09:29:56
发布于 2018-01-18 09:29:56
84000
代码可运行
举报
运行总次数:0
代码可运行

前言

 最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。  本篇将阐述国际化和本地化的概念,以及其中一个很重要的概念——Language tag(也叫Language code 或 Culture)。

何为国际化?

 国际化我认为就是应用支持多语言和文化习俗(数字、货币、日期和字符比较算法等),而本地化则是应用能识别用户所属文化习俗自动适配至相应的语言文化版本。  过去常常以为国际化就是字符串的替换——如"你好!"替换为"What's up, man!",其实具体是分为以下5方面:

  1. 字符串替换  如"你好!"替换为"What's up, man!".
  2. 数字表示方式  如1200.01,英语表示方式为1,200.01,而法语则为1 200,01,德语则为1.200,01.
  3. 货币表示方式  如人民币¥1,200.01,美元表示方式为$1,200.01,而英语的欧元则为€1,200.01,德语的欧元则为1.200,01 €. 注意: 这里没有还没算上汇率呢.
  4. 日期表示方式  如2016年9月15日,英语表示方式为9/15/2016, 而法语为15/9/2016, 德语为15.9.2016.
  5. 字符比较算法  如äz比较时,英语、德语中均是ä排在z前面,而在瑞典语中则是z排在ä前面.

本地化的关键 —— Language Tag

既然要自动适配至用户所属的语言文化版本,那么总得有个根据才能识别吧?我想大家应该对zh-CNen等不陌生吧,而它们正是我们所需的根据了!在我们使用已有i18n库实现国际化/本地化时,必定会写下以下文档

代码语言:js
AI代码解释
复制
{
    "en": { "name": "Enter Name " },
    "zh-CN": { "name": "输入姓名" } 
}

但除了enzh-CN还有其"Enter Name "是如何的呢?下面我们来稍微深入的了解这些Language Tag吧!

语法规则

注意以下采用ABNF语言描述(ABNF的语法请参考语法规范:BNF与ABNF)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Language-Tag = langtag
             / privateuse
             / grandfathered

langtag = language
          ["-" script]
          ["-" region]
          *("-" variant)
          *("-" extension)
          ["-" privateuse]

可以看到Language-Tag分为langtagprivateusegrandfatherd三个子类,下面我们先了解一般情况用不上的两个吧! privateuse  标签的意思不由subtag registry定义,而是由使用的团队间私自定义、维护和使用。  格式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
privateuse = "x" 1*("-" (1*8alphanum))

示例:x-zh-CN是privateuse,其意思不一定与languagezh-CN一致。 注意: 只作为小集团内部用可以,决不能大范围适用。

grandfathered  用于向后兼容。由于RFC 4646前的标签无法完全匹配当前registry的标签语法和意思,因此通过grandfathered来提供向后兼容的特性。  语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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,用于标识资源所对应的语言。  语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
language = 2*3ALPAH
           ["-" extlang]
         / 4ALPHA
         / 5*8ALPHA
extlang = 3ALPHA
          *2("-" 3ALPHA)

看到language有三种形式,其中让我比较好奇的是第一种2*3ALPHA ["-" extlang]。这种形式中前面的2*3ALPHA称为macrolanguage,用于标明资源对应一种语言的汇总,而具体的某一种语言/方言则通过extlang指定。而包含extlang部分的language也被称为encompassed language. 如zh-cmnzh-yue就是encompassed language,其中zh是macrolanguage,而cmnyue则是extlang。  这里有个很有趣的事情是,我们认为普通话和广东话等都是汉语的方言,但西方却认为普通话、广东话根本就不属于一种语言,因此像zh-cmnzh-yue在规范中被设置为redundant,建议直接使用cmnyue等。不过由于历史原因,我们还是使用zh-CN代表cmn-CN。  另外现在可以作为macrolanguage的就只有7个标签(ar,kok,ms,sw,uz,zhsgn)  另外几个和cmn类似的subtags如下

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cmn 普通话(官话、国语)
wuu 吴语(江浙话、上海话)
czh 徽语(徽州话、严州话、吴语-徽严片)
hak 客家语
yue 粤语(广东话)
nan 闽南语(福建话、台语)
cpx 莆仙话(莆田话、兴化语)
cdo 闽东语
mnp 闽北语
zco 闽中语
gan 赣语(江西话)
hsn 湘语(湖南话)
cjy 晋语(山西话、陕北话)

注意: 一般采用全小写

Script subtag

 用于指定字迹或文字系统资源所属的语言和方言等。  语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
script = 4ALPHA

注意: 一般采用首字母大写,后续字母全小写

Region subtag

 指定与国家、地域对应的语言/方言文化。  语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
region = 2ALPHA
       / 3DIGIT

注意: 一般采用全大写

Variant subtag

 指定其他subtag又无法提供的额外信息  语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
variant = 5*8alphanum
        / (DIGIT 3alphanum)

示例:de-CH-1996其中1996是variant subtag,整体意思是在Switzerland使用的自1996改良过的德语。

Extension subtag

 提供一种机制让我们去扩展langtag  语法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
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:下文普通话、粤语并存

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<p lang="cmn">
小陈说:"老大爷,东方广场怎么走啊?"
老大爷回答道:"<span lang="yue">你讲咩也啊?我听唔明喔。</span>"
</p>

示例2:下文含大陆人讲英语、中国香港人讲普通话和美国人说英语

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<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魔法堂:不完全国际化&本地化手册 之 实战篇》

感谢

网页头部的声明应该是用 lang="zh" 还是 lang="zh-cn"? Language Subtag Registry BCP 47 Language on the Web Choosing a Language Tag Language tags in HTML and XML

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2016-09-26 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Django 实战:I18N 国际化与本地化配置、翻译与切换一步到位
国际化和本地化的目标,是允许一个单一的 Web 应用程序以适合受众的语言和格式提供其内容。 Django 提供了完整的国际化(i18n)和本地化(l10n)支持。
小王子1024
2025/07/18
110
Django 实战:I18N 国际化与本地化配置、翻译与切换一步到位
JS魔法堂:不完全国际化&本地化手册 之 拓展篇
前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下,为后面的技术选型做准备。  本篇作为系列的最后一篇,打算和大家一起看看HTTP的Content Negotiation机制和更多关于本地化的应用方向。 Content Negotiation(内容协同)  记得第一次接触国际化和本地化时是指服务端根据请求头字段Accept-Language获取languag
^_^肥仔John
2018/01/18
5430
JS魔法堂:不完全国际化&本地化手册 之 拓展篇
深入Go:Internationalization-国际化
我们通常可以在HTTP header里看见类似于Accept-Language: zh-CN或是Accept-Language: en之类的值,这里header里对应的值就是语言标签。类似地,zh-cmn-Hans-CN也是语言标签。
wenxing
2021/12/14
1.2K0
2016年2月9日 Go生态洞察:Go语言中的语言和地区匹配
🐯 猫头虎博主在此!今天我们来探讨Go语言中如何处理语言和地区的匹配问题,这是构建多语言应用程序时的一个重要考虑。在这篇博客中,我们将深入了解Go如何帮助解决这一挑战。搜索词条:Go语言,语言标签,地区匹配。
猫头虎
2024/04/08
1470
2016年2月9日 Go生态洞察:Go语言中的语言和地区匹配
如何使用Spring Boot轻松实现国际化和本地化
国际化(Internationalization) 是指为了适应不同语言、文化和地区的用户,使软件能够方便地进行本地化修改的过程。国际化(Internationalization) 简称i18n,其中 “i” 是Internationalization的首字母 ,“n” 是最后一个字母 , “18” 代表了中间省略的18个字母。
索码理
2024/02/22
3.8K2
如何使用Spring Boot轻松实现国际化和本地化
JS魔法堂:不完全国际化&本地化手册 之 实战篇
前言  最近加入到新项目组负责前端技术预研和选型,其中涉及到一个熟悉又陌生的需求——国际化&本地化。熟悉的是之前的项目也玩过,陌生的是之前的实现仅仅停留在"有"的阶段而已。趁着这个机会好好学习整理一下
^_^肥仔John
2018/01/18
1.6K0
JS魔法堂:不完全国际化&本地化手册 之 实战篇
Spring Boot 国际化踩坑指南
国际化,也叫 i18n,为啥叫这个名字呢?因为国际化英文是 internationalization ,在 i 和 n 之间有 18 个字母,所以叫 i18n。我们的应用如果做了国际化就可以在不同的语言环境下,方便的进行切换,最常见的就是中文和英文之间的切换,国际化这个功能也是相当的常见。
江南一点雨
2020/03/06
1.4K0
Spring Boot 国际化踩坑指南
HarmonyOS Next快速入门:类型定义和国际化
##HarmonyOS Next快速入门##HarmonyOS应用开发##教育##
中雨
2025/06/24
670
Next.js 实战 (四):i18n 国际化的最优方案实践
有关 Next.js 国际化的方案网上很多,而且各部相同,但大部分的方案都是在 /app 目录下添加动态路由 [lang] 这样的形式,这不是我想要的效果。
白雾茫茫丶
2024/12/11
9701
Next.js 实战 (四):i18n 国际化的最优方案实践
国际化语种名称的标识
国内因为版号的问题,导致很多游戏厂商选择出海。在国际化的市场要想取得好的成绩,就必须要做好深度的本地化,其中最基础的一块就是语言。
meteoric
2018/11/20
2.7K0
Java国际化/本地化实战
开发一个支持多国语言的Web应用程序,要求系统能够根据客户端的系统的语言类型返回对应的界面:英文的操作系统返回英文界面,而中文的操作系统则返回中文界面——这便是典型的i18n国际化问题。
JavaEdge
2020/05/27
2.5K0
Java国际化/本地化实战
译|你不知道的CSS国际化
我遇到过一些人,他们根本不认为CSS与国际化有关,但如果你仔细想想,国际化不仅仅是把你网站上的内容翻译成多种语言,然后就收工了。该内容的呈现方式有各种细微的差别,这些细微的差别会影响到母语人士使用您的网站的体验。
张张
2020/05/09
1.7K0
译|你不知道的CSS国际化
从零玩转后端接口数据交互国际化
当我们的项目涉及到多语言支持时,身为后端开发的我们,接口数据国际化便是我们必须攻克的问题。
Blue_007
2023/11/06
4.8K7
从零玩转后端接口数据交互国际化
Spring之 国际化:i18n
国际化也称作i18n,其来源是英文单词 internationalization的首末字符i和n,18为中间的字符数。由于软件发行可能面向多个国家,对于不同国家的用户,软件显示不同语言的过程就是国际化。通常来讲,软件中的国际化是通过配置文件来实现的,假设要支撑两种语言,那么就需要两个版本的配置文件。
叫我阿杰好了
2024/01/04
9760
Spring之 国际化:i18n
3分钟实现iOS语言本地化/国际化(图文详解)
语言本地化,又叫做语言国际化。是指根据用户操作系统的语言设置,自动将应用程序的语言设置为和用户操作系统语言一致的语言。往往一些应用程序需要提供给多个国家的人群使用,或者一个国家有多种语言,这就要求应用程序所展示的文字、图片等信息,能够让讲不同语言的用户读懂、看懂。进而提出为同一个应用程序适配多种语言,也即是国际化。语言国际化之所以又叫做语言本地化,这是站在每个用户的角度而言的,是指能够让用户本地、本土人群能够看懂的语言信息,顾名思义,语言本地化。其实语言本地化 == 语言国际化! 本文将分如下7个主要章节一步一步讲解如何完全本地化一个App。
VV木公子
2018/06/05
18.5K0
这篇文章让你搞懂 SpringMVC 国际化!
松哥原创的 Spring Boot 视频教程已经杀青,感兴趣的小伙伴戳这里-->Spring Boot+Vue+微人事视频教程
江南一点雨
2021/04/22
1.2K0
这篇文章让你搞懂 SpringMVC 国际化!
四种方式解决页面国际化问题——步骤详解
最近在做公司的网站,但是有一个是比较麻烦的事情就是需要做的一个国际化,我们都知道后端其实做国际化的话是直接可以配置的,相对来说是比较简单的,但是前端做国际化的话是很麻烦的一件事情,但是不是说不可以做,我之前呢是准备直接做两套网站,这样一样可以实现国际化的效果,其实这也是过去网站国际化的一个做法,包括现在也有人这样做,这个办法我们就不具体的写了,因为很简单,直接一模一样的写两份,一份是中文的一份是英文的就行了!其实我没写之前看了很多的资料,关于国际化的,很多的大神提供了很多的办法,但是都不是很详细,写的很模糊,所以我查看很多资料以后决定写这篇博客,总结一下自己的想法,同时希望可以帮助很多的人解决这个问题!
何处锦绣不灰堆
2020/05/29
1.5K0
Vue-i18n 国际化
上边写的当前的语言切换是默认的状态,初始化的时候一定加载的是默认的,比如默认的是中文,无论你后期改成什么状态,最后重新加载时一定是中文
全栈程序员站长
2022/08/15
8070
Vue-i18n 国际化
初识ABP vNext(6):vue+ABP实现国际化
上一篇介绍了ABP扩展实体,并且在前端部分新增了身份认证管理和租户管理的菜单,在实现这两个功能模块前,先来解决一下界面文字国际化的问题。
xhznl
2020/08/28
1.6K0
初识ABP vNext(6):vue+ABP实现国际化
jquery/vue/react前端多语言国际化翻译方案指南
每个开发者能希望编写的程序可以让全世界的用户使用,它要求从产品中抽离所有地域语言,国家/地区和文化相关的元素。换种说法,「应用程序」的功能和「代码设计」时考虑在不同地区运行的需要,其代码适应不同区域要求。开发这样的的过程,就称为国际化( internationalization),简称i18n。
Tz一号
2021/09/08
2.9K0
相关推荐
Django 实战:I18N 国际化与本地化配置、翻译与切换一步到位
更多 >
交个朋友
加入腾讯云官网粉丝站
蹲全网底价单品 享第一手活动信息
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档