典型的java i18n流程——将资源文件发送给翻译公司进行翻译

发布于 2024-09-19 00:30:59 字数 333 浏览 8 评论 0原文

有大量关于使用 Java ResourceBundles 提供多种语言 UI 的教程。然而,有一个关于与翻译公司的典型互动的流程问题,我似乎找不到答案。

例如,假设我不懂法语,并且需要雇用翻译公司来为我的应用程序获取翻译,我会向他们发送

  1. 默认资源属性文件“whatever_en_US.properties”,包括密钥和英语值,然后返回“ whatever_fr_FR.properties”?
  2. “whatever_fr_FR.properties”具有空值和“whatever_en_US.properties”供参考?
  3. 其他一些组合?

There are loads of tutorials on using Java ResourceBundles to provide UI in multiple languages. However, there is a process question as regards typical interaction with translation companies that I can't seem to find an answer to.

Assuming for example that I don't know French, and need to employ a translation company to get translations for my app, would I send them

  1. The default resource properties file "whatever_en_US.properties" including the key and English value, and get back "whatever_fr_FR.properties"?
  2. "whatever_fr_FR.properties" with empty values and "whatever_en_US.properties" for reference?
  3. some other combination?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

铜锣湾横着走 2024-09-26 00:30:59

由于您的问题是关于流程而不是技术,因此我将尽力为您提供全面的解释。假设您的应用程序之前没有翻译,理想的流程应如下所示:

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

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

  3. 如果您想同时发布(同时发布所有语言),您需要尽早聘请翻译人员。由于 UI 字符串会发生变化(假设没有硬 UI 冻结期或翻译冻结期),因此您必须更新翻译。在这种情况下,您需要提供已翻译的文件以及需要翻译的字符串(英文)。如果更改确实很小,您可以仅发送英文字符串并手动合并翻译,否则最好使用某种翻译记忆库交换格式(gettext *.po 或 trados *.tmx 在这里很棒)。

  4. 翻译文件通常是不够的。由于通常没有给出上下文,并且不同的单词在目标语言中可能意味着不同的事物,因此会出现翻译错误。除非您懂得该语言,否则无法知道他们是否在其中。这就是为什么您需要拍摄 UI 屏幕截图并将其发送出去以供审核(可以由您的翻译承包商或其他人根据质量要求进行审核)。

  5. 审核后,您将需要应用翻译更改并测试 UI 问题...

就是这样,如果我们是的话谈论UI字符串翻译过程。但请注意,正确本地化应用程序还需要很多东西(文档、帮助文件、图标、颜色、声音...)。

Since your question is about a process and not about technology, I will try to give you thorough explanation. Assuming that you have application with no previous translation, the ideal process should look like:

  1. Send English files for translation. Depending on your agreement with translation contractor you could use:

    • Your default properties files (you will be responsible for renaming them correctly)
    • Excell spreadsheet containing keys, English phrase and an empty column for translation
    • Gettext *.po file(s) if you are going to use gettext
    • Translation memory file(s) (i.e. Trados *.tmx files)
  2. When you receive files back, you put these translations into product, create localized build and test it out. Surely, there will be some UI issues. Some of them you could fix on your own, some will require additional translation (like hardcoded strings), others will require shortening translation. Again, you will engage translation contractor and supply them with strings that need to be (re-)translated. You could use spreadsheet here (provided that there are not so many strings that need to be translated).

  3. If you want to ship simultaneously (all languages at once), you need to engage translators early. Since UI strings will change (provided there is no hard-UI-freeze period or translation-freeze period), you will have to get your translations updated. In this case, you will need to supply already translated files with the strings that need to be translated (in English). If the changes are really small, you could send only the English strings and merge translations manually, otherwise it is best to use some kind of translation memory exchange format (gettext *.po's or trados *.tmx's are great here).

  4. Translating files is usually not enough. Since usually there is no context given and different words may mean different things in a target language, translation errors occur. There is no way to know that they are in unless you know the language. That's why you need to take UI screenshots and send them out for review (it could be reviewed by your translation contractor, or somebody else depending on quality requirements).

  5. Once reviewed, you will need to apply translation changes and test for UI issues...

That's about it, if we are talking about UI strings translation process. But please be advised that there is a lot of more to correctly localize an application (documentation, help files, icons, colors, sounds...).

坏尐絯℡ 2024-09-26 00:30:59

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

在实践中,我发现对我来说使用其他东西比使用 Java 资源包要容易得多。

我个人使用不同的方式来处理这个问题。我使用 gettext 方式(那里有一个名为 GetTextResource.java 的文件,您必须在应用程序中使用该文件才能从 gettext 扩展中受益 - 请参阅 此处)。

如果您熟悉 gettext,您一定会发现这种方法更加简单实用。您只需将 po 文件提供给翻译人员(可以使用 poedit 进行编辑)。从 po 文件中,您创建将在应用程序中使用的 java 类(这是使用 msgfmt 完成的 - 指定 po 文件的 java 编译参数)。使用 xgettext 命令(从命令行)可以相当容易地更新 Po 文件。

当然,所有内容都在 gettext 手册中。

优点:

  • gettext 为您提供了一种选择复数形式的方法 [ 不再有诸如“N 个文件已删除”(其中 N 是数字)之类的消息 - 请参阅 ngettext

  • 使用新标记更新 Java 文件后,用于翻译字符串的可编写脚本的方法

  • 无需使用某些宏访问每个字符串(像翻译(DELETE_BUTTON_MACRO))。您只需像这样编写代码:

    包translateutil;        
    导入 gnu.gettext.GettextResource;
    
    导入java.util.ResourceBundle;
    
    导入java.util.Locale;
    
    公共类 TranslateUtil
    {
    私有静态ResourceBundle myResources = null;
    
    公共静态布尔初始化(区域设置 loc,字符串资源名称)
    {
        布尔值 bRet = true;
        Locale.setDefault(loc);
    
        尝试
        {
            myResources = ResourceBundle.getBundle(resourceName);
    
            System.out.printf( _("当前语言:%s\n"),
                                Locale.getDefault().getDisplayName() );
    
            System.out.printf( _("找到%s资源\n"),
                                myResources.getClass().getName() );
        }
        捕获(异常 e)
        {
            // 让应用程序以英语继续,以防 ResourceBundle
            // 没有找到。通知错误
            bRet=假;
            System.out.println( e.toString() );
            我的资源=空;
        }
    
        返回bRet;
    }
    
    
    公共静态字符串_(字符串str)
    {
        if (myResources == null)
        {
            返回字符串;
        }
        {
            返回 GettextResource.gettext(myResources, str);
        }
    }
    
    public static String _Plural(字符串单数,字符串复数,长参数)
    {
        if (myResources == null)
        {
            如果(参数==1)
            {
                返回单数;
            }
            别的
            {
                返回复数;
            }
        }
        别的
        {
            返回 GettextResource.ngettext(myResources, 单数, 复数, 参数);
        }
    }
    }
    

这是一个示例

    // example
    // similar for plural

    import static translateutil.TranslateUtil._;

    System.out.println(_("The english text"));

无论您选择什么:祝您好运!

To answer your question I would chose (2).

In practice I found that for me it is a lot easier to use something else rather than the Java resource bundles.

I personally use a different way of handling this. I use the gettext way (there is a file there called GetTextResource.java that you must use in your application to benefit from the gettext extensions - see here).

If you're familiar with gettext you will definitely find this approach a lot easier and practical. You simply give to your translators the po files (which can be edited with poedit). From the po files you create the java class you will use inside your application (this is done using msgfmt - specifying parameters for java compilation of the po files). Po files can be updated fairly easy using the xgettext command (from command line).

Of course everything is inside the gettext manual.

Advantages:

  • gettext offers you a way to select the plural form [ No more messages like: "N file(s) deleted" (where N is a number) - see ngettext.

  • a scriptable method for translating strings once your java files are updated with new tokens

  • no need to access each string using some macros (like Translate(DELETE_BUTTON_MACRO) ). You just write your code like this:

    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);
        }
    }
    }
    

Here is a sample

    // example
    // similar for plural

    import static translateutil.TranslateUtil._;

    System.out.println(_("The english text"));

No matter what you choice is: Good luck!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文