Angular 应用国际化
2020-07-01

如何 Angular i18n,不做过多赘述,有任何问题,请移步 官网

背景

当前端页面有大批量更新,trans-unit 有大幅变动(新增、更改 context-group 或删除等等)时,如果人工手动去调整,工作量大不说,很容易出错。所以必须想办法去自动更新。

我的解决方案

在没有去搜索引擎找寻方案的前提下,下面是自己写的 C# 控制台项目:

  1. 备份当前 messages.zh.xlf 文件。
  2. 新建 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
79
namespace 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));
}
}
}
  1. 复制 messages.zh.xlf 到当前项目的根目录,并重命名未 history.xlf
  2. 运行命令 ng xi18n --output-path locale 重新生成新的 messages.xlf 文件。
  3. 复制 messages.xlf 到当前项目的根目录,并重命名未 now.xlf
  4. history.xlfnow.xlf 文件设置成 copy always。
  5. 运行项目,得到 output.xlf(位于项目根目录/bin/Debug)。
  6. 复制 messages.xlf 到 Angular 的 locale 文件夹,并重命名未 messages.zh.xlf
  7. 打开 messages.zh.xlf,找到所有后面不是 target 节点的 source 节点 (很多 IDE 支持正则或者换行符查找)。
  8. 补全 target 节点

当当当当,新鲜的 message.zh.xlf 出炉啦!

本文链接:
content_copy https://zxs66.github.io/2020/07/01/Angular-internationalization/