代码之家  ›  专栏  ›  技术社区  ›  jwl

典型的JAVA I18N进程——向翻译公司发送翻译的资源文件

  •  5
  • jwl  · 技术社区  · 15 年前

    使用Java资源包提供多种语言的UI有很多教程。但是,有一个 过程 关于与翻译公司的典型互动问题,我似乎找不到答案。

    例如,假设我不懂法语,需要雇佣翻译公司为我的应用程序翻译,我会发送给他们吗?

    1. 默认的资源属性文件“whatever-en-us.properties”包括关键字和英文值,并返回“whatever-fr-fr.properties”?
    2. “whatever-fr-fr.properties”和“whatever-en-us.properties”作为参考?
    3. 其他组合?
    2 回复  |  直到 15 年前
        1
  •  4
  •   Paweł Dyda    15 年前

    既然你的问题是关于一个过程而不是技术,我会尽力给你详细的解释。假设您的应用程序没有以前的翻译,理想的过程应该如下所示:

    1. 发送英文文件进行翻译。根据您与翻译承包商的协议,您可以使用:

      • 您的默认属性文件(您将负责正确重命名它们)
      • Excell电子表格,包含用于翻译的键、英文短语和空列
      • 如果要使用gettex,则返回gettext*.po文件
      • 翻译内存文件(即trados*.tmx文件)
    2. 当您收到返回的文件时,您将这些翻译放到产品中,创建本地化的构建并测试它。当然,会有一些UI问题。其中一些你可以自己修复,一些需要额外的翻译(如硬编码字符串),另一些需要缩短翻译。同样,您将聘请翻译承包商,并向他们提供需要(重新)翻译的字符串。您可以在这里使用电子表格(前提是不需要翻译太多的字符串)。

    3. 如果您想同时发货(所有语言同时发货),您需要尽早聘用翻译人员。由于用户界面字符串将发生更改(如果没有硬用户界面冻结期或翻译冻结期),您必须更新翻译。在这种情况下,您需要提供已经翻译的文件,其中包含需要翻译的字符串(英语)。如果更改非常小,您可以只发送英文字符串并手动合并翻译,否则最好使用某种翻译内存交换格式(gettext*.po's或trados*.tmx's在这里非常好)。

    4. 翻译文件通常是不够的。由于在目标语言中通常没有上下文,不同的词可能意味着不同的事物,因此会出现翻译错误。如果你不懂他们的语言,就无法知道他们在那里。这就是为什么你需要截取用户界面截图并发送给他们进行审查的原因(它可以由你的翻译承包商或其他人进行审查,具体取决于质量要求)。

    5. 一旦审阅,您将需要应用翻译更改并测试UI问题…

    这就是它,如果我们谈论的是UI字符串转换过程。但是请注意,要正确地本地化应用程序还有很多(文档、帮助文件、图标、颜色、声音…)。

        2
  •  2
  •   INS    15 年前

    为了回答你的问题,我选择(2)。

    在实践中,我发现使用其他东西比Java资源包更容易。

    我个人用不同的方式来处理这个问题。我使用gettex方法(这里有一个名为gettexresource.java的文件,您必须在应用程序中使用该文件才能从gettex扩展中获益-请参见 here )

    如果 你很熟悉GetText,你肯定会发现这种方法更简单、更实用。您只需向翻译人员提供采购订单文件(可使用 poedit )从PO文件中创建您将在应用程序内部使用的Java类(这是使用MSGFMT-指定用于PO文件的Java编译的参数)来完成的。使用xgettext命令(从命令行)可以非常容易地更新po文件。

    当然一切都在里面 gettext manual .

    优势:

    • GetText为您提供了一种选择复数形式的方法[不再显示诸如“n个文件已删除”(其中n是一个数字)的消息-请参见 ngettext .

    • 一个用新令牌更新Java文件后的字符串转换脚本方法

    • 不需要使用一些宏(如translate(删除按钮)宏)访问每个字符串。您只需这样编写代码:

      package translateutil;        
      import gnu.gettext.GettextResource;
      
      import java.util.ResourceBundle;
      
      import java.util.Locale;
      
      public class TranslateUtil
      {
      private static ResourceBundle myResources =null;
      
      public static boolean init(Locale loc, String resourceName)
      {
          boolean bRet = true;
          Locale.setDefault(loc);
      
          try
          {
              myResources = ResourceBundle.getBundle(resourceName);
      
              System.out.printf(  _("Current language: %s\n"),
                                  Locale.getDefault().getDisplayName() );
      
              System.out.printf(  _("%s resource found\n"),
                                  myResources.getClass().getName() );
          }
          catch(Exception e)
          {
              // let the application go on in English in case the ResourceBundle
              // was not found. Notify about the error
              bRet = false;
              System.out.println( e.toString() );
              myResources = null;
          }
      
          return bRet;
      }
      
      
      public static String _(String str)
      {
          if (myResources == null)
          {
              return str;
          }
          {
              return GettextResource.gettext(myResources, str);
          }
      }
      
      public static String _Plural(String singular, String plural, long param)
      {
          if (myResources == null)
          {
              if (param == 1)
              {
                  return singular;
              }
              else
              {
                  return plural;
              }
          }
          else
          {
              return GettextResource.ngettext(myResources, singular, plural, param);
          }
      }
      }
      

    这是一个样品

        // example
        // similar for plural
    
        import static translateutil.TranslateUtil._;
    
        System.out.println(_("The english text"));
    

    不管你选择什么:祝你好运!