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

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

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