Angular 应用国际化
2020-07-01
如何 Angular i18n,不做过多赘述,有任何问题,请移步 官网。
背景
当前端页面有大批量更新,trans-unit
有大幅变动(新增、更改 context-group
或删除等等)时,如果人工手动去调整,工作量大不说,很容易出错。所以必须想办法去自动更新。
我的解决方案
在没有去搜索引擎找寻方案的前提下,下面是自己写的 C# 控制台项目:
- 备份当前
messages.zh.xlf
文件。 - 新建 C# 控制台项目,复制如下代码:ZXS66/GenerateNewI18NFile.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79namespace ConsoleApp
{
class Program
{
static void Main(string[] args)
{
generateNewI18NFile();
return;
}
private static void generateNewI18NFile()
{
// step 1: extract all translations from history.xlf
// trans-unit@id, target
IDictionary<string, string> dict = new Dictionary<string, string>();
string[] allLines = File.ReadAllLines
(
"./history.xlf",
Encoding.UTF8 //Encoding.Default
);
string lastTransUnitId = string.Empty;
string lastTarget = string.Empty;
foreach (string line in allLines)
{
string line_trimed = line.Trim();
if (line_trimed.StartsWith("<trans-unit "))
{
int firstQuote = line_trimed.IndexOf("\""), secondQuote = line_trimed.IndexOf("\"", firstQuote + 1);
lastTransUnitId = line_trimed.Substring(firstQuote + 1, secondQuote - firstQuote - 1);
continue;
}
if (line_trimed.StartsWith("<target>"))
{
// all target values are inside one line
lastTarget = line;
dict.Add(lastTransUnitId, lastTarget);
}
}
// step 2: generate new translation file by appending target node
List<string> outputLines = new List<string>();
allLines = File.ReadAllLines("./now.xlf", Encoding.Default);
string[] prefixOfIgnoreLines = new string[]
{
"<?xml ",
"<xliff ",
"<file ",
"<body>",
"</body>",
"</file>",
"</xliff>"
};
foreach (string line in allLines)
{
outputLines.Add(line);
string line_trimed = line.Trim();
if (prefixOfIgnoreLines.Any(_ => line_trimed.StartsWith(_)))
continue;
if (line_trimed.StartsWith("<trans-unit "))
{
int firstQuote = line_trimed.IndexOf("\""), secondQuote = line_trimed.IndexOf("\"", firstQuote + 1);
lastTransUnitId = line_trimed.Substring(firstQuote + 1, secondQuote - firstQuote - 1);
continue;
}
if (line_trimed.EndsWith("</source>"))
{
lastTarget = dict.ContainsKey(lastTransUnitId) ? dict[lastTransUnitId] : string.Empty;
if (!string.IsNullOrEmpty(lastTarget))
{
outputLines.Add(lastTarget);
}
}
}
// step 3: write result to file
File.WriteAllLines("./output.xlf", outputLines);
//Console.WriteLine(string.Join(Environment.NewLine, outputLines));
}
}
} - 复制
messages.zh.xlf
到当前项目的根目录,并重命名未history.xlf
。 - 运行命令
ng xi18n --output-path locale
重新生成新的messages.xlf
文件。 - 复制
messages.xlf
到当前项目的根目录,并重命名未now.xlf
。 - 将
history.xlf
和now.xlf
文件设置成 copy always。 - 运行项目,得到
output.xlf
(位于项目根目录/bin/Debug)。 - 复制
messages.xlf
到 Angular 的locale
文件夹,并重命名未messages.zh.xlf
。 - 打开
messages.zh.xlf
,找到所有后面不是target
节点的source
节点 (很多 IDE 支持正则或者换行符查找)。 - 补全
target
节点
当当当当,新鲜的 message.zh.xlf
出炉啦!
本文链接:
content_copy https://zxs66.github.io/2020/07/01/Angular-internationalization/