我最初为Wayfair的内部前端文档写了这些准则。这里是一个经过修改和改进的版本。下面的例子都是使用React和React Intl库,但这些建议对Web应用来说是通用的,可以应用于任何框架和国际化库。
1.不要串联字符串
不完整的短语很难甚至不可能被翻译,因为译者看不到整个短语的内容。而且,各部分的顺序在其他语言中可能是不同的。
将一个短语的所有相关部分合并成一个本地化字符串,并对动态内容使用插值,而不是将一个句子分割成多个本地化字符串。
不好。
<p>
<FormattedMessage
id="homepage.firstGreetingText"
defaultMessage="Hey "
/>
{name}
<FormattedMessage
id="homepage.secondGreetingText"
defaultMessage=", welcome back!"
/>
</p>
好的。
<p>
<FormattedMessage
id="homepage.greetingText"
defaultMessage="Hey {name}, welcome back!"
values={{ name }}
/>
</p>
例如。英语中的 "红铅笔 "在法语中是 "crayon rouge"(注意单词顺序的颠倒)。
2.不要嵌套字符串
与前面的提示类似,嵌套的字符串很难翻译,因为翻译者只看到短语的一部分。
保持一个完整的短语作为一个单一的本地化字符串,并使用标签插值来添加格式化或动态元素,如链接或按钮。这在你的国际化库中可能是不同的或不可能的。
不好。
<p>
<FormattedMessage
id="landingPage.termsConditionsText"
defaultMessage="By selection “Purchase” below, you agree to our <a />."
values={{
a: () => (
<a href={TERMS_URL}>
<FormattedMessage
id="landingPage.termsConditionsLink"
defaultMessage="Terms & Conditions"
/>
</a>
)
}}
/>
</p>
好的。
<p>
<FormattedMessage
id="landingPage.termsConditionsText"
defaultMessage="By selection “Purchase” below, you agree to our <a>Terms & Conditions</a>."
values={{
a: (...chunks) => <a href={TERMS_URL}>{chunks}</a>
}}
/>
</p>
3.不要在本地化字符串之外硬编码标点符号
不同的语言可能以不同的方式使用标点符号:例如,字符周围的间距不同,甚至不同的字符。
把标点符号放在本地化字符串中,而不是在代码中添加。
不好。
<p>
<FormattedMessage
id="registration.usernameLabel"
defaultMessage="Username"
/>
: <input type="text" />
</p>
好的。
<label>
<FormattedMessage
id="registration.usernameLabel"
defaultMessage="Username:"
/>{' '}
<input type="text" />
</label>
例子。英语中的 "用户名: "在法语中是 "Nom d'utilisateur :"(注意冒号前的空格)。
4.不要在不同的语境中重复使用译文
同样的英文字符串在不同的语境中可能会有不同的翻译,或者一个翻译可以为一个特定的页面进行调整而没有意识到它会影响其他页面。
为你的功能创建独特的本地化字符串,而不是在许多地方重复使用看起来相同的英文短语。
不好。
<FormattedMessage id="bookmark" defaultMessage="Bookmark" />
好的。
<FormattedMessage
id="productCard.bookmarkButtonLabel"
defaultMessage="Bookmark"
/>
例子。英文的 "书签 "标题和 "书签 "按钮标签在俄文中应该是 "Закладка "和 "Добавить в закладки"。
5.不要硬编码复数化
许多语言有比英语更复杂的复数规则,并且有两个以上的复数形式。
使用你的国际化库的复数化功能,而不是在词尾添加s。
不好。
<p>
{resultCount > 1 ? (
<FormattedMessage id="NumberResults">
{resultCount} dogs found
</FormattedMessage>
) : (
<FormattedMessage id="NumberResult">
{resultCount} dog found
</FormattedMessage>
)}
</p>
坏的。
<p>
<FormattedMessage id="NumberResults">
{resultCount} dog(s)
</FormattedMessage>
</p>
好的。
<p>
<FormattedMessage id="search.numberResults">
{resultCount, plural, one {# dog} other {# dogs}} found
</FormattedMessage>
</p>
例子。英语中的 "1只狗,2只狗,5只狗 "和俄语中的 "1собака,2собаки,5собак"。
6.不要在你的网页中注入HTML
将第三方的HTML直接注入你的页面可能会破坏你的应用程序,甚至让黑客有机会获取你的用户数据。
只从后端发送数据,并在前端翻译文本,而不是将已经翻译好的文本作为HTML发送。
不好。
<span dangerouslySetInnerHTML={{ __html: message }} />
好的。
<FormattedMessage
id="reviews.successMessage"
defaultMessage="Thanks for sharing! You’ve been entered to win a {amount} shopping spree!"
values={{ amount }}
/>
奖励:不要使用 "哑巴引号"
这并不完全是一个国际化的问题,但仍然值得一提。
使用不正确的排版字符使我们的页面看起来不专业。
使用正确的排版字符,如引号、撇号或破折号(“”’—),而不是我们在代码中使用的字符("'-)。
不好。
<FormattedMessage
id="homepage.lunchCta"
defaultMessage='Ready to say "lunch!"'
/>
好的。
<FormattedMessage
id="homepage.lunchCta"
defaultMessage="Ready to say “lunch!”"
/>
结论
这些最佳实践的目的是给翻译人员更多的背景,使他们能够产生更好的翻译,因此你的非英语用户将有更好的体验。有时,一个不正确或不恰当的翻译会使用户无法理解界面和如何使用它。
这里有一些关于国际化和网页排版的好资源。
- 本地化内容的最佳实践,MDN
- 软件本地化的12条戒律, Smashing杂志
- 聪明人的聪明语录
- 引语和重音(及破折号)