小语种的本地化数据,看着有的多半是借的,看着空的反而是对的
本文目录
- 那个向上的箭头是什么意思?
- 它不是乱码,是一个正式定义的标记
- 这个标记是2019年这一版才大规模出现的
- 你在实际用的那份数据里看不到这个标记
- 顺带解决了一个长期存在的假象
- 把箭头剔掉之后,各门语言还剩多少?
- 三门西非语言站在一头,六成以上是借的
- 中间那一档是什么形状
- 越南语这一行要单独解释
- 这张表该怎么用,不该怎么用
- 数字本身有个天花板要注意
- 那些借来的格子,具体落在哪几块上?
- 度量单位那一整块,自己填的是零
- 为什么语言名称那一块反而填得最满
- 换一门语言对照,这个形状就不一样了
- 一个反向的例子值得记住
- 对你的页面意味着什么
- 为什么en_US那个文件只有527字节?
- 空壳文件在这份数据里占了一大半
- 527字节这个数字本身说明了什么
- 哪些是空壳,哪些不是,能反推出默认值是谁
- 有两个地区代码不对应任何一个国家
- 不是空壳的那些,反而是要小心的
- 你以为的父语言,可能不是真的父语言
- 有一张显式的父级映射表,覆盖了直觉
- 有一批变体的父级被直接指向了最顶层
- 葡萄牙语那一支的方向跟别人相反
- 繁体中文是这里面最反直觉的一条
- 标注为未确认的那些格子,最后会被丢掉吗?
- 四个等级,只有两级会被发出去
- 未确认的格子在页面上表现成什么样
- 怎么查一门语言的草案状态
- 已贡献这一级容易被误读
- 这些东西在页面上会表现成什么样?
- 第一类:格式偏了,但页面完全正常
- 第二类:单位和连接词以英语形式混在句子里
- 第四类:搜索结果和列表的顺序不对
- 第三类:引号和标点掉成方框
- 上线前怎么用二十分钟查一遍?
- 第一步:确认你实际配的是哪个代码
- 第二步:查那个带后缀的文件有多大
- 第三步:数一遍那门语言的继承标记
- 这四步查不出来的两件事
- 第四步:把结论写成一句话
- 哪些相邻的问题不归这一层管?
- 词典和分词是另一份资源
- 翻译质量不在这一层
- 字体和渲染是再往下一层
- 搜索引擎那一侧是另一套账
- 常见问题解答
- 怎么快速知道一门语言的格式数据是不是借的?
- 文件是空的,是不是说明这门语言没做本地化?
- 我该配带地区的代码还是不带的?
- 为什么翻译审校查不出这类问题?
- 已贡献状态的数据能用吗?
- 这些问题值得花多少工时?
- 为什么同一门语言不同工具查出来的字段数不一样?
- 权威参考资料
摘要:把公共区域数据仓库里759个语言版本的原始文件逐格数了一遍。第一,看着有的多半是借的——豪萨语文件里66.1%的格子明确写着跟上级一样,度量单位那一整块1117格里自己填的是0。第二,看着空的反而常常是对的,en_US、de_DE、fr_FR、pt_BR这些文件都只有527字节,因为老家就是默认值。第三,这两件事以前分不开,2019年这一版第一次给继承加了标记,才第一次数得出来。
做多语言站的人都干过这么一件事:想知道某门语言的日期、数字、货币写法有没有人做过,于是去查一眼公共的区域数据。查到了,文件在,几百KB,心里踏实了,转头去忙别的。
保哥今年秋天把这个动作认真做了一遍,把759个语言版本的原始文件全下下来,一格一格数。数完发现,刚才那个踏实来得太早了。
问题不在于数据有没有,而在于“有”这个字在这份数据里至少有三种意思:有人认真填了本地的写法、有人看过之后确认跟上级一样、没人看过所以什么都没有。前两种在文件里长得几乎一样,第三种干脆不出现在文件里。
更拧巴的是另一头。你按市场去查,查到en_US这个文件只有527字节,几乎是空的,很容易得出美式英语没做的结论。事实正好相反,那份文件空是因为它就是默认值,不需要再写一遍。
一头是看着有的其实是借的,一头是看着空的其实是对的。两个方向的直觉都错,而且错的方向相反。下面这些数字是为了把这两头掰回来。
那个向上的箭头是什么意思?
先说这一批数据里最扎眼的东西。打开豪萨语的文件,会看到大量长这样的行:一个字段名,里面写着三个向上的箭头。
它不是乱码,是一个正式定义的标记
三个向上箭头这个符号,在区域数据标记语言规范里有正式名字,叫继承标记。规范里的原话是:它用于在数据提交阶段记录“这个继承来的值已经针对当前语言和当前路径被验证过”。
翻成人话就是:有个人坐在那里,看到这一格是空的,系统按规则给他显示了上级语言的值,他看了一眼,觉得对,按了确认。这一按,就在文件里留下一个箭头。
规范里举的例子是德语的瑞士版本。上级德语里“阿布哈兹语”这个词条写作Abchasisch,有人确认瑞士德语也是这么写,于是瑞士德语那一格就记成箭头,而不是把Abchasisch再抄一遍。
所以这个标记本身是个好东西。它把“确认过一样”和“没人看过”这两件事第一次分开了,而在此之前,这两件事在文件里完全无法区分——都表现为该字段不存在。
规范里还强调了一点:这个标记只出现在主仓库里,是数据提交流程的产物,不属于最终数据格式的一部分。这句话对我们的意义是,它记录的是人的动作,不是语言的属性。
这个标记是2019年这一版才大规模出现的
保哥把同一门语言的八个历史版本并排数了一遍,结论很干净:2017年那一版、2018年那一版、乃至2019年春天那一版,箭头数量都是0;到2019年10月这一版,箭头突然大量出现。
这不是语言变了,是记录方式变了。这一版的发布说明里写着,仓库开始保留针对继承值的投票记录,并且新增了一个工具在生成发布数据时把这些标记解析掉。
对我们来说,这意味着一件很实际的事:2019年之前你没法数出一门语言有多少格是借来的,因为借来的和没人管的写在一起。2019年之后可以数了。
这也意味着,如果你手上有一份两年前做的语言能力评估表,那张表里“字段数”那一列的口径跟今天不是一回事,不能直接比。
换个角度说,2019年这一版第一次让外人能看见本地化流程里发生了什么。在此之前,这份数据只呈现结果,不呈现过程。
你在实际用的那份数据里看不到这个标记
这个标记只存在于源文件里。生成给程序用的发布数据时,它会被解析成上级语言的实际值,然后消失。
所以如果你是通过某个前端库或者某份JSON包去查这门语言有没有数据,你永远看不到箭头,只会看到一个填好的值——那个值是英语的,但它长得跟本地填的一模一样。
这解释了一个长期现象:很多团队查过区域数据,得出的结论都是齐全的,因为他们查的是解析之后那一层。要看到借来的痕迹,必须去看源文件,而不是看运行时的返回值。
这也是本篇所有数字都基于原始文件的原因。换一个数据源,同一门语言会得出完全不同的结论,而且是更好看的那一种。
顺带解决了一个长期存在的假象
标记出现之后,某些语言的文件字段数会突然暴涨,因为原来不写的格子现在都写出来了。豪萨语从春天那一版的1200格涨到秋天这一版的4348格,涨了262%。
如果只看这个数,会得出豪萨语的本地化在半年里突飞猛进的结论。但把箭头剔掉之后,真正填进去的从1136格涨到1465格,只涨了29%。
一个数据量涨了两倍多,另一个数据量涨了不到三成,说的是同一件事。差别只在于你把那些确认过跟上级一样的格子算不算数。
这就是本篇要讲的第一件事:查这门语言有没有数据的时候,字段总数这个指标已经不能单独用了。
把箭头剔掉之后,各门语言还剩多少?
下面这张表是2019年10月这一版,五十门语言逐格数出来的结果。真自有率的算法是:把值等于继承标记的格子剔掉,再把标注为未确认和暂定的格子剔掉,剩下的除以总格数。
三门西非语言站在一头,六成以上是借的
| 语言 | 总格数 | 继承标记 | 真自有 | 真自有率 |
|---|---|---|---|---|
| 豪萨语 | 4348 | 2876 | 1465 | 33.7% |
| 伊博语 | 3084 | 2004 | 1068 | 34.6% |
| 约鲁巴语 | 3131 | 1949 | 1169 | 37.3% |
| 越南语 | 6566 | 1890 | 4676 | 71.2% |
| 索马里语 | 4477 | 1019 | 3441 | 76.9% |
| 祖鲁语 | 5109 | 727 | 4382 | 85.8% |
| 波兰语 | 6918 | 703 | 6172 | 89.2% |
| 马来语 | 5477 | 556 | 4921 | 89.8% |
| 英语 | 5556 | 0 | 5556 | 100.0% |
豪萨语、伊博语、约鲁巴语是尼日利亚的三大语言,加起来覆盖两亿多人口。三门语言的真自有率都在33%到38%之间,三分之二的格子写着跟上级一样。
要说明的是,跟上级一样这件事本身不一定错。有些字段确实全世界通用,比如某些技术性的格式模板。问题在于比例——三分之二这个量级,说明这不是逐格判断的结果,而是整块整块过的。
另一头英语是0,因为英语就是那个上级,它没有可继承的对象。这一行的作用是给整张表提供一个刻度:100%在这里不是优秀,是定义。
需要说清楚的是,这三门语言在语言名称那一块填得都不差,说明维护它们的人是在认真做事的。差距落在格式层,而格式层的门槛比翻译层高得多。
中间那一档是什么形状
索马里语和祖鲁语落在中间。索马里语总格数4477,其中1019格是借的,真自有3441,占76.9%;祖鲁语5109格里727格是借的,真自有4382,占85.8%。
索马里语值得多看一眼,因为它的曲线很陡:2017年那一版总共只有795格,2018年跳到3477格,两年里翻了四倍多。这是典型的有人接手了的形状。
祖鲁语的形状则平缓得多,几年里稳步爬升。陡增说明有组织的一次性投入,缓增说明有个人在持续维护,两者对未来的预期完全不同。
做技术选型的时候,这两种形状的判读方式不一样:陡增的语言要问一句那次投入是不是一次性的,缓增的语言可以按现状线性外推。
越南语这一行要单独解释
越南语看起来还行,71.2%,但它的绝对数字很反常:1890个格子标着继承标记,而它上一版的总格数是4985,这一版真自有4676——真自有反而比上一版的总数还少了三百多格。
这不是数据被删了。合理的解释是,这1890格里有相当一批,在上一版是把父语言的值原样抄了一遍写在里面的,看起来是自己填的;这一版换成了标记,值没变,性质第一次被写明。
换句话说,越南语这一行的变化不是能力变化,是坦白。它以前显示的自有量里,本来就有一块是抄来的,只不过没人知道。
做越南语这门语言的技术评估时,这一点值得记一笔:它的基础数据成色比总量看起来的要薄一层,但薄得有限,跟西非那三门不是一个量级。
这也提醒了一件事:任何一个跨版本的对比,都要先确认两版的记录规则一样。规则变了,趋势就是假的。
这张表该怎么用,不该怎么用
该用的方式是横向比同一门语言的不同区块,或者比几门候选语言的同一个区块。这两种比较的口径是一致的。
不该用的方式是拿总格数给语言排名,也不该拿这一版的绝对值去跟别的版本比。前面已经说过,2019年这一版的计数口径跟之前不同。
还有一种误用是把真自有率当成本地化质量的分数。它不是分数,它只回答一个问题:这门语言的格式层有多大一块直接等于英语。
至于那一块等于英语要不要紧,取决于这门语言跟英语在格式习惯上差多远。差得远的,比例低就是大问题;差不多的,比例低也没什么。
数字本身有个天花板要注意
这张表里最厚的一门语言总格数接近一万,最薄的不到一千,差了将近十倍。但这个差距不能直接读成能力差十倍。
原因是格数里有一大块是“别的语言叫什么名字”这类词条,一门语言只要有人把两百多种语言的名字都翻一遍,格数立刻上去几百。这一块对你的商品页几乎没有影响。
所以看总量之前,得先知道这些格子分布在哪几块上。下一节把它拆开。
顺带说一句,这也是为什么保哥不建议直接拿字段总数给语言排优先级——它跟排优先级真正该看的那几个量不是一回事。
保哥自己第一版就是按总格数排的,排出来豪萨语在五十门语言里排中游,看着挺正常。剔掉箭头之后它掉到了倒数第几名。一个指标能让结论反过来,那它就不该单独用。
那些借来的格子,具体落在哪几块上?
把豪萨语的文件按功能区块拆开,继承标记的分布一点都不平均。这一节是本篇对做站的人最直接的一节。
度量单位那一整块,自己填的是零
| 区块 | 管什么 | 总格数 | 豪萨语真自有 |
|---|---|---|---|
| units | 千克、厘米、天、小时的写法 | 1117 | 0 |
| delimiters | 引号用哪一对符号 | 4 | 0 |
| characters | 这门语言用哪些字符 | 28 | 4 |
| numbers | 小数点、千分位、货币格式 | 824 | 149 |
| listPatterns | 三个词并列怎么连 | 36 | 14 |
| dates | 日期时间怎么写 | 1492 | 738 |
| localeDisplayNames | 各种语言地区叫什么名字 | 680 | 558 |
度量单位1117格,真自有0格,全部是确认跟上级一样。引号那4格也是0。这意味着豪萨语页面上如果按系统默认渲染,引号用的就是英语那一对,单位说法也是英语那一套。
这不是漏了,是有人明确按过确认。整整1117次。
相比之下,语言名称那一块680格填了558格。规律很清楚:翻译者认真做了那些一眼能看出是翻译活的部分,而把格式性质的部分整块放过去了。
把这1117格摊开看,里面是千克、米、秒、天、小时这些日常单位在单数复数各种情形下的说法。对一个卖实物商品的站来说,这一块几乎每张商品页都用得到。
为什么语言名称那一块反而填得最满
豪萨语680格的语言名称填了558格,是它填得最满的一块。其他所有语言的这一块也普遍高于其他区块。
原因不难猜:这一块的内容是“阿拉伯语在豪萨语里叫什么”这类问题,一眼就知道是翻译活,谁都能上手,而且做起来有成就感——一次能填几百格。
度量单位那一块则完全不同。它的内容是模板,长得像代码,里面有占位符,填之前得先搞清楚这门语言的复数规则和词序。
翻译者优先做那些看起来像翻译的部分,而格式层恰好是最不像翻译的那部分。这个规律在别的本地化项目上也成立,不是这份数据独有的。
换一门语言对照,这个形状就不一样了
| 语言 | units真自有/总 | numbers真自有/总 | 引号 真自有/总 |
|---|---|---|---|
| 豪萨语 | 0 / 1117 | 149 / 824 | 0 / 4 |
| 伊博语 | 6 / 770 | 96 / 631 | 0 / 4 |
| 约鲁巴语 | 65 / 770 | 105 / 607 | 4 / 4 |
| 越南语 | 539 / 853 | 683 / 828 | 4 / 4 |
| 缅甸语 | 761 / 799 | 677 / 679 | 4 / 4 |
| 高棉语 | 687 / 799 | 637 / 637 | 4 / 4 |
| 斯瓦希里语 | 1110 / 1178 | 855 / 855 | 4 / 4 |
| 泰语 | 760 / 806 | 919 / 919 | 4 / 4 |
| 英语 | 1564 / 1564 | 1008 / 1008 | 4 / 4 |
缅甸语和高棉语的数字格式是全填的,一格不差。这两门语言在别的维度上通常被归到资源最少的那一档,可在这一格上比尼日利亚那三门语言强得多。
斯瓦希里语的度量单位1178格填了1110格。同样在非洲,同样是志愿者维护,形状完全不同。
所以这不是地区问题也不是资源问题,是维护这门语言的那几个人当时选择从哪一块开始动手的问题。
还有一个细节:伊博语的引号那4格是0,约鲁巴语是4。同一个国家的两门语言,同一个区块,一个整块借着一个自己填了。这种粒度的差异只能实测。
一个反向的例子值得记住
缅甸语的数字格式679格填了677格,高棉语637格一格不差全填了,泰语919格也是全填。这三门语言在很多能力评估里被归到资源最少的那一档。
而豪萨语的数字格式824格只填了149格。豪萨语的使用者人数比高棉语多得多。
这个反差说明,格式数据的成色跟使用人数、跟这门语言在网上的内容量都没有稳定关系。它取决于有没有一个懂技术又懂这门语言的人在某一年坐下来把它填完。
所以这一格必须逐门语言实测,不能从别的指标推断。这是本篇最该记住的一条方法论:这一层没有代理指标。
对你的页面意味着什么
把上面的表倒过来读,就是一张风险清单。数字格式那一块借来的比例高,意味着价格的小数点和千分位可能按英语规则渲染。
度量单位那一块借来的,意味着商品规格里的重量长度单位名称会以英语形式出现在本地语言的句子中间。
引号那一格借来的,意味着你的评论区、商品描述里的引用会用英语的弯引号,而不是这门语言习惯的符号。这一条视觉上最不起眼,但它跟字体那一层的取舍会叠在一起出问题:字体里没有那个符号,就会掉成方框。
这三样的共同点是,它们都不在翻译稿里,所以任何一轮母语审校流程都碰不到它们。审校看的是你给的文案,而这些东西是系统渲染出来的。
这三类的共同点还有一个:它们都不会出现在任何一份翻译交付物里,所以在项目管理上它们没有负责人。没有负责人的东西不会被排进任何一个迭代。
为什么en_US那个文件只有527字节?
换一头。前面讲的是看着有的其实是借的,这一节讲反过来的那一半:看着空的其实是对的。
空壳文件在这份数据里占了一大半
759个语言版本文件里,327个不到700字节,另有100个在700到1500字节之间。加起来427个,占56.3%。这些文件打开之后除了一个身份声明段,什么都没有。
但空壳的分布极其规律。带地区或书写系统后缀的变体一共551个,其中427个是空壳,占77.5%;而不带后缀的纯语言代码一共208个,空壳数量是0。
一个都没有。这个整齐程度本身就是个信号:空不是随机发生的,是有规则的。
规则就是:如果这个地区的写法跟语言默认值完全一致,就不需要写任何东西。文件存在只是为了声明这个组合是合法的。
反过来讲,如果哪天你看到一个纯语言代码的文件也是空壳,那才是真的出事了——那说明这门语言被登记了,但一个字段都没人填过。这一版里这种情况是0个。
527字节这个数字本身说明了什么
空壳文件的字节数高度集中在527这个值上。打开看,里面是版权声明、文档类型声明,加上一个身份段,写着这个文件对应哪门语言、哪个地区。
数据段一个字节都没有。文件存在的全部意义是声明这个组合合法,并且告诉解析器不用再往下找了。
527这个数字之所以整齐,是因为这些文件是工具生成的,模板一样,只有语言代码和地区代码那两处不同。
顺带说一句,如果你看到某个变体文件在1000到1500字节之间,多半是里面多了一两个字段。这一档最值得打开看,因为那一两个字段就是这个地区的全部特殊性。
哪些是空壳,哪些不是,能反推出默认值是谁
| 语言 | 空壳的那个 | 有数据的那个 | 说明默认值是谁 |
|---|---|---|---|
| 葡萄牙语 | pt_BR(527字节) | pt_PT(344KB) | 默认是巴西 |
| 西班牙语 | es_ES(527字节) | es_MX(312KB) | 默认是西班牙 |
| 英语 | en_US(527字节) | en_GB(392KB) | 默认是美国 |
| 繁体中文 | zh_Hant_TW(551字节) | zh_Hant_HK(632KB) | 默认是台湾 |
| 斯瓦希里语 | sw_TZ(527字节) | sw_KE(304KB) | 默认是坦桑尼亚 |
| 阿拉伯语 | ar_EG(1045字节) | ar_SA(265KB) | 默认接近埃及 |
葡萄牙语这一行值得停一下。做葡语两个市场的人,直觉上会把pt理解成葡萄牙,把pt_BR理解成巴西的变体。这份数据里正好反过来:pt本身就是巴西葡语,葡萄牙那一版才是需要单独写出来的那个。
所以如果你的系统里配的是pt,用户在里斯本,他看到的日期和数字格式是巴西的。这个错误不会报任何异常,页面也是葡萄牙语的,只是格式偏了。
西班牙语的默认值则是西班牙,跟西语两侧市场那套词汇分叉的处理逻辑正好错开——词汇上通常要按拉美单独做,格式上默认值却站在西班牙那边。
这张表也可以当成一份历史记录来读:默认值站在哪一边,基本反映了这份数据最早成型的那几年,谁在贡献、谁的用例被优先考虑。
有两个地区代码不对应任何一个国家
前面提到的en_001和en_150,这两个代码后面的数字不是国家代码。001代表全世界,150代表欧洲。
它们是为了解决一个实际问题造出来的:英语在几十个国家用,这些国家的写法大多一致但都跟美式不同,如果每个国家写一遍就是几十份重复数据。于是造一个国际英语放公共部分。
en_001有57KB的实际内容,en_150只有2174字节。也就是说欧洲英语跟国际英语的差别很小,只有那么两千多字节。
西班牙语的es_419也是同类,419代表拉丁美洲。看到代码后面跟的是数字而不是字母,就要意识到这不是一个国家,是一组国家的公共层。
不是空壳的那些,反而是要小心的
反过来看,一个地区文件如果有几百KB,说明这个地区跟语言默认值差得远。这些才是需要在配置里显式写清楚的。
荷兰语的比利时版本是5317字节,德语的奥地利版本5126字节,瑞士版本8897字节。数字不大,但不是零,说明确实有一批字段不一样。
做荷兰语两个市场的时候,这几KB就是佛兰芒那一侧格式层的全部差异。它不多,但它存在,而且写它的人是为了它不一样才写的。
判据可以固化成一句:文件大不代表做得好,代表跟默认不一样;文件空不代表没做,代表这里就是默认。
顺着这条判据往下推还有一层:某个地区文件从空壳变成有内容,说明有人发现了差异并提交了。所以文件的历史变化本身就是一份差异发现记录。
你以为的父语言,可能不是真的父语言
继承这件事还有第二层坑:往上一级到底是哪一级,不是按代码字面截断的。
有一张显式的父级映射表,覆盖了直觉
按字面直觉,en_AU往上一级应该是en。实际上这份数据里有一张显式的映射表,把八十多个英语地区变体的父级统一指向了en_001,也就是国际英语。
en和en_001的差别不小,日期顺序、部分拼写都不同。所以en_AU拿到的默认值不是美式的,是国际式的。这符合直觉的结果,但走的不是直觉的路径。
更绕的是第二层:en_DE、en_NL、en_SE这一批欧洲国家的英语,父级被指向en_150,也就是欧洲英语,而en_150的父级才是en_001。三级。
西班牙语同理,es_MX、es_AR这一批的父级是es_419拉美西语,不是es。
这张表在数据里是显式写出来的,不是靠代码推导。也就是说它可以随版本变化,而且确实变过。锁死版本再做判断,这一条在这里格外重要。
有一批变体的父级被直接指向了最顶层
更值得注意的是另一批。sr_Latn、uz_Cyrl、az_Cyrl、ms_Arab、ha_Arab、pa_Arab、ug_Cyrl、mn_Mong这些带书写系统后缀的组合,父级被显式指向了最顶层的root。
意思是:塞尔维亚语的拉丁字母版本,不继承塞尔维亚语;乌兹别克语的西里尔版本,不继承乌兹别克语。它们跳过所有中间层,直接掉到最上面那份通用数据。
这个设计有它的道理——换了书写系统之后,排序规则、数字写法、断行规则可能全都不一样,继承过来反而是错的。但对配置的人来说,后果是:你写sr_Latn,实际拿到的是一份非常薄的通用数据。运行时具体按什么顺序往上找,写在ICU的资源回落文档里。
做塞尔维亚语双文字站的人对这条会有实感:两套字母在内容层是两套关键词,在格式数据层则是一套有本地数据、另一套掉到最顶层。
清单里那些组合有个共同点:书写系统换了之后,字符集、排序、断行几乎没有一样能沿用。与其继承一份错的,不如什么都不继承。
葡萄牙语那一支的方向跟别人相反
葡萄牙语的地区变体里,pt_AO安哥拉、pt_MZ莫桑比克、pt_CV佛得角这一批的父级被指向了pt_PT,而不是pt。
连起来看就是:pt本身是巴西葡语,非洲那几个葡语国家跟着葡萄牙走,只有巴西自己跟着默认值走。
这个安排符合语言现实——非洲葡语国家的书面规范历史上跟着里斯本,跟巴西那一套不一样。但它在配置层面很容易配错。
如果你要做安哥拉市场,配pt和配pt_AO拿到的是两套不同的格式数据,而且差别不在两个字母上,在中间隔着的那一级上。
繁体中文是这里面最反直觉的一条
zh_Hant的父级也在那张root清单里。也就是说,繁体中文不继承zh,直接到最顶层。
好在zh_Hant自己的文件有722KB,是全表最厚的之一,掉到root也不影响什么。但如果换成清单里那些薄的组合,后果就完全不同。
判断方法很简单:先看这个带后缀的组合自己的文件有多大。厚,说明它自食其力;薄,而且父级被指向root,那就是真的什么都没有。
这一条跟书写系统在地址层的选择是两件事,别混在一起决策:地址那边是可见性问题,这边是有没有数据的问题。
还有一个实用的判断法:看这个组合在不在那张父级映射表里。在表里的,父级不是你截断代码得到的那个;不在表里的,才是按字面往上一级。
标注为未确认的那些格子,最后会被丢掉吗?
除了继承标记,还有第三类看着有、其实没有的东西:草案状态。
四个等级,只有两级会被发出去
每一格数据都可以带一个草案属性,取值从低到高是未确认、暂定、已贡献,不带这个属性表示已批准。生成发布数据的时候,未确认和暂定这两级会被剔掉。
所以一格数据在源文件里存在,不等于它会出现在你实际用到的那份数据里。这是继承标记之外的第二道过滤。
法语在这一版有1726格标着未确认,占总格数的21.6%。法语。这说明这件事跟语言大小没关系,跟这门语言最近有没有开过一轮大规模数据征集有关。
相比之下英语这一列是0,因为英语的数据是基准,不走投票流程。
这套等级的存在本身说明了一件事:这份数据是靠投票和审核维护的,不是靠一个权威机构发布的。所以它的质量分布必然不均匀,而不均匀的地方需要你自己去量。
未确认的格子在页面上表现成什么样
未确认的格子会在生成发布数据时被剔掉,所以它的表现跟这一格从来没人填过完全一样:回落到上级语言的值。
这就造成一个很坑的现象:你去源文件里查,看到这一格有内容,是本地语言写的,于是判定没问题;上线之后页面上显示的却是英语。
后面那篇讲历法的文章里会有一个极端例子:某门语言的某套历法在源文件里确实有一条本地写法,但它标着未确认,所以实际发布出去的是一个英文缩写。
判据固化:在源文件里看到值,还要看它带不带草案属性,两步缺一不可。
怎么查一门语言的草案状态
方法跟查继承标记一样,在文件里搜索草案属性,统计各个取值的出现次数。四个取值里只有未确认和暂定这两个会被丢掉。
要注意的是,同一个属性可以标在不同层级上:标在一个大区块上,整个区块都受影响;标在单个字段上,只影响那一格。统计的时候要分开数。
法语那1726个未确认里,相当一部分是集中在几个区块上的,不是散落在各处。这种形状说明是一次批量提交还没走完流程,不是长期问题。
散落型才麻烦。它意味着这些格子是不同的人在不同时间提交的,每一格都要单独走一遍流程,而且没有人负责推动。
已贡献这一级容易被误读
已贡献这一级会被发出去,所以它不影响可用性。但它数量很大:繁体中文4687格、越南语2539格、马来语1430格、泰语1379格。
这些是有人提交了、还没走完批准流程的数据。它们能用,只是意味着这门语言正处在一轮数据更新中间,下一版可能会变。
做技术选型的时候,这一列的意义不是能不能用,而是稳不稳定。已贡献占比高的语言,两个版本之间的格式差异会比别的语言大。
把三种状态并排:继承标记是明确不填,未确认是填了不算,已贡献是填了算但还在动。三种都不是你以为的那个“有”。
做一个简单的对照就明白了:英语这一列是0,法语的未确认是1726,繁体中文的已贡献是4687。三个数字代表三种完全不同的状态,而它们在很多统计里会被合并成同一个“有数据”。
这些东西在页面上会表现成什么样?
到这里为止都是文件层的事。这一节把它翻译成用户实际会看到的东西。
第一类:格式偏了,但页面完全正常
最常见的表现是价格和日期的写法不对。小数点该用逗号的地方用了点,千分位该用空格的地方用了逗号。
这类问题不报错、不影响布局、截图看不出来,除非有人真的懂那门语言并且盯着数字看。它通常是被本地客服转述用户抱怨的形式发现的,而客服往往会转述成“价格显示有点怪”。
更麻烦的一种是数字被理解错。1,234在有些语言里读作一千二百三十四,在有些语言里读作一点二三四。差一千倍。
这一条跟工具返回零数据那件事是同一类毛病:系统正常返回了一个值,而那个值的口径不是你以为的口径。
这类问题最好的发现办法不是检查,是让本地同事在真实页面上下一单。走一遍完整流程,价格出现在购物车、结算页、确认邮件三个地方,只要有一处写法不对就会被注意到。
第二类:单位和连接词以英语形式混在句子里
商品规格里写重量,系统按单位模板渲染,模板是借来的,于是本地语言的句子里出现了英语的单位说法。
并列连接同理。三个属性并排展示,中间的连接词按模板拼,模板是借来的,出来就是英语的逗号加and。
这类问题视觉上很显眼,一眼能看出来,反而不容易漏。真正会漏的是它出现在筛选器、面包屑这些没人逐字检查的地方。
还有一种更隐蔽的:这些拼出来的字符串会进标题和描述,而锚文本和标题的一致性检查不会把它们当成异常,因为从字符层面看它们没错。
顺带提一句,这类拼接出来的字符串还会进入商品结构化数据。地名那种一名两写的问题是内容层的,这个是渲染层的,但它们最后落到同一个字段里。
第四类:搜索结果和列表的顺序不对
排序规则也住在这一层。一门语言的字母顺序、变音符号怎么参与比较、大小写怎么折叠,都是区域数据的一部分。
这一格借来之后,站内搜索的结果顺序、商品列表的字母排序、下拉选项的排列,全部按英语规则来。用户会觉得列表是乱的,但说不出哪里乱。
这类问题的排查成本比前三类都高,因为它没有一个可以指着说错了的点,只有一种整体上不对劲的感觉。
好在排序这一格的借用率通常比单位和引号低,因为它属于覆盖等级评定的必查项,做到基本档就得填。大小写折叠在土耳其语上出的那类事,根子也在这一格。
第三类:引号和标点掉成方框
引号那一格借来之后,页面上出现的是英语那对弯引号。如果这门语言的网页字体子集是按本地字符集裁的,这两个符号可能不在里面。
结果是用户看到两个方框。这个现象最容易被误诊成字体加载失败,然后有人花两天去查字体文件,而根子在几千公里外的一格区域数据上。
排查顺序应该反过来:先看那个符号是什么码位,再看它是谁决定的,最后才看字体有没有它。
说句题外话,保哥见过一次这样的排查,三个人查了一周,最后是一个做本地化的实习生随口说了一句“我们的语言不用这种引号”,才把方向掰回来。
这一类还有个变种:并非掉成方框,而是字体里有这个符号但形状不对。西里尔和拉丁共用码位的那些标点尤其容易出这种事,视觉上只差一点点,本地人一眼看得出。
上线前怎么用二十分钟查一遍?
这一节是可执行的部分。不需要读整份规范,四步就够。
第一步:确认你实际配的是哪个代码
先把配置里那串语言代码找出来,注意它可能出现在三个地方:页面的语言属性、后端的区域设置、以及某些前端库自己的配置项。三处不一致很常见。
然后判断这个代码带不带地区或书写系统后缀。不带的,直接查那门语言;带的,进第二步。
选代码的原则在官方那份选代码指引里写得很清楚,核心是别写多余的子标签。多写一层不会让数据更准,只会多一层回落。
顺带一提,语言标签本身的合法写法由RFC 5646规定,这一步别自己发明写法。
三处不一致的时候,以后端那一处为准去查数据,因为格式化通常发生在后端或者服务端渲染阶段。页面属性那一处影响的是别的东西。
第二步:查那个带后缀的文件有多大
去公共仓库里找到对应的文件,看字节数。小于1500字节的,说明它是空壳,你实际拿到的是上一级的数据。
这时候要做的不是换代码,而是确认上一级是不是你想要的。参照前面那张表,默认值经常不是使用人数最多的那个地区。
大于100KB的,说明这个地区确实有一套自己的数据,配上它是对的。
中间那一档,几KB到几十KB,说明只有少数字段不同。这一档最需要打开看一眼具体是哪几个字段,因为差异可能正好落在你用得上的地方,也可能完全无关。
字节数只是个粗筛,准确的做法是数字段数。但对上线前的快速判断来说,字节数够用了,因为空壳和有内容之间差了两个数量级,不存在误判空间。
第三步:数一遍那门语言的继承标记
打开那门语言的主文件,搜索三个向上箭头这个符号,数出现次数,除以总的字段数。
超过三成,说明这门语言的格式层很大一块是英语默认值,价格、单位、引号都要人工验一遍。低于一成,基本可以放心用默认渲染。
更精细一点,可以只看三块:单位、数字、引号。这三块跟商品页直接相关,其他块可以先放着。
这一步花不了五分钟,但它决定了你要不要在排期里加一项人工校验。
如果你要给多门语言做这件事,把这三步写成一个脚本比手工快得多。输入是语言代码清单,输出是三列数字,跑一次十几分钟。
这四步查不出来的两件事
第一件是你的技术栈实际用的是哪一版区域数据。运行时的版本可能比你查的那一版老好几年,中间的补充全都用不上。查依赖树里那个库的版本号,比查数据本身更重要。
第二件是你的框架有没有自己覆盖过这些值。不少前端框架带一份精简的内置数据,只挑常用的几十个语言版本,而且精简的口径不公开。
这两件事都得在自己的项目里查,没有公共答案。查完公共数据只解决了一半,另一半在你的依赖里。
实操上的顺序是:先查公共数据判断这门语言值不值得信默认渲染,再查依赖确认你实际拿到的是不是那一版。
第四步:把结论写成一句话
最后把三步的结果合成一句:这门语言的格式数据里有多少是它自己的,我配的那个代码会落到哪一级,以及哪几类页面元素需要人工验。
这句话应该跟着语言进排期表,跟词典能力、字体能力并列。它们分属不同的层,但都是上线前该有答案的。
需要提醒的是,这一层的结论不该影响选哪门语言的顺序。它影响的是选定之后要预留多少工时。
把两件事混在一起判断,很容易得出因为数据不全就不做这门语言的错误结论,而实际上这里的缺口大多是几十个工时能补的。
这句话还有一个用处:它是跟供应商谈判时的筹码。对方说支持一百多种语言的时候,你可以问其中有多少门的格式数据自有率超过九成。这个问题多数供应商答不上来。
哪些相邻的问题不归这一层管?
这一层很容易跟旁边几层混起来,划一下界。
词典和分词是另一份资源
站内搜索召回不好、拼写纠错不灵,根子在词典和词法资源上,跟本篇讲的格式数据是两套完全独立的文件,由完全不同的人维护。
两者的成色经常不一致:格式数据完整的语言,词典可能停更十年;反过来也有。查一层的结论不能推另一层。
判断方法也不同。格式数据看字段数和继承标记,词典看最后更新时间和词条数。
这两层唯一的共同点是,它们都不在你的代码库里,都是借来的。
实际操作上建议把两层的查询结果并排放在一张表里,各占一列。不一致的那几行是最值得看的,它们说明这门语言的支持是偏科的,而偏在哪一科决定了你该补什么。
翻译质量不在这一层
页面上的文案读着别扭、语气不对、用词不地道,属于翻译质量问题,跟格式数据无关。哪怕格式数据100%自有,文案照样可能是机器翻译直接发上线的。
反过来,文案由母语者精心打磨过的站,格式层照样可能整块借着英语。这两件事在流程上完全不相交。
区分方法很简单:看这段字符是你的团队写进内容库的,还是系统渲染出来的。前者归翻译,后者归本篇这一层。
大多数验收流程只覆盖前者,这就是后者长期没人管的原因。
有一个简单的分界问题可以帮你判断:如果把这门语言换成英语,这个问题还在不在?在,就是格式层;不在,多半是翻译层。
字体和渲染是再往下一层
这一层决定用哪个符号,字体那一层决定这个符号画不画得出来。两层都对了才有正确的显示。
顺序上先查这一层:确认系统会输出哪个码位,再去看字体子集里有没有它。反过来查会绕远路,因为字体缺字的表现和数据借错的表现在屏幕上是一样的,都是不对劲。
这两层的负责人通常也不是同一批人。数据这一层归本地化或者后端,字体那一层归前端。中间那道缝就是问题最容易掉进去的地方。
把这句话写进排查手册的第一行会省很多时间:先问这个字符是谁决定的,再问它为什么画不出来。
搜索引擎那一侧是另一套账
这一层的数据决定的是浏览器和服务端怎么渲染,不决定搜索引擎怎么理解你的页面。引擎有自己的一套语言识别和格式解析。
所以格式数据不全不会直接导致排名问题。它导致的是转化问题——用户看到一个写法奇怪的价格,会犹豫。
真正跟收录相关的是页面上声明的语言代码有没有写对,而那是另一套规则。
把这两件事分开的好处是,排查的时候不会把一个转化问题当成排名问题来治。
还有一层也不归这里管:内容本身的组织方式,比如同一门语言在两个市场该不该拆成两套落地页。那是意图分叉那一类的问题,跟数据文件无关。
常见问题解答
怎么快速知道一门语言的格式数据是不是借的?
打开公共仓库里这门语言的主文件,搜索三个向上箭头这个符号,数出现次数,再除以总字段数。这个比值就是借来的比例。超过三成要人工验价格、单位和引号这三样,低于一成可以直接用默认渲染。注意这个数只有2019年10月及之后的版本才有意义,更早的版本里借来的和没人填的写在一起,分不出来。如果你只想花两分钟,就只看单位、数字、引号这三块,它们跟商品页直接相关。
文件是空的,是不是说明这门语言没做本地化?
正好相反的情况更常见。带地区后缀的文件为空,通常说明这个地区的写法跟语言默认值完全一致,不需要重复写一遍。全部551个带后缀的变体里有427个是空壳,而208个纯语言代码里空壳数量是0。判断的时候不要看那个空文件,要去看它上一级是谁、上一级有没有数据。真正要担心的是另一种情况:带书写系统后缀的组合,自己是空壳,而父级又被显式指向了最顶层。
我该配带地区的代码还是不带的?
先查那个带地区的文件有没有实际内容。有几百KB的,配上它;只有几百字节的空壳,配不配都一样,那就选短的那个,少一层回落少一个出错的地方。中间那一档要打开看差异落在哪几个字段上。另外记住默认值经常不是你以为的那个地区:葡萄牙语的默认是巴西,繁体中文的默认是台湾,斯瓦希里语的默认是坦桑尼亚。配错了页面不会报错,只是格式站到了另一边。
为什么翻译审校查不出这类问题?
因为审校看的是你交给他的文案,而这些东西不在文案里,是系统渲染的时候临时拼出来的。引号、单位说法、并列连接词、日期顺序,这四样都不会出现在任何一份待审稿件上。要覆盖它们,得在验收清单里单独加一条:让母语者看渲染后的真实页面,重点看数字、日期和标点,而不是看文档。这一条加上之后,绝大多数这类问题在上线前一小时就能发现。
已贡献状态的数据能用吗?
能用,它会进发布数据。真正会被剔掉的是未确认和暂定这两级。已贡献这一列的意义不在于能不能用,而在于稳不稳定:这个数字大,说明这门语言正处在一轮数据更新的中途,下一个版本的格式可能会跟这一版不一样。繁体中文、越南语、马来语、泰语这一版的已贡献量都很大。如果你的站有大量缓存好的格式化字符串,升级依赖库的时候要留意这几门语言。
这些问题值得花多少工时?
查的部分很便宜,一门语言二十分钟,十门语言半天能查完。补的部分要看缺在哪:单位和引号这类是配置层的事,写死在你自己的模板里几个小时就能解决;数字和日期格式要谨慎,因为改错了比借着英语还糟。保哥的建议是先查全,再只补那些直接出现在价格和规格上的,其余的记在文档里,等有人反馈再动。
为什么同一门语言不同工具查出来的字段数不一样?
大概率是版本不同,或者一个查的是原始文件、另一个查的是解析之后的发布数据。发布数据里继承标记已经被替换成实际值,未确认的格子已经被剔掉,所以两个数不可能一样。做对比的时候必须锁死是哪一版、哪一种形态。这跟看语言能力的其他指标一样,口径比数值重要。
本文标题:《小语种的本地化数据,看着有的多半是借的,看着空的反而是对的》
本文链接:https://zhangwenbao.com/minor-language-locale-data-inheritance.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0