这不是您问题的直接答案,而是解决您问题的不同解决方案。另一个答案解决了如何在技术上实现您想要的,但是使用反射进行一些国际化是不必要的脆弱,绝对不推荐。
正如评论中提到的,当您在 Play 应用程序的上下文中使用 Twirl 时,Play 为您提供了自己的国际化方式。由于您不在应用程序中使用 Play,因此您不能使用它。但是你不需要使用 Play 的特定方式来做国际化。您可以轻松构建自己的基本国际化结构,而无需引入额外的依赖项,我将在此答案中展示。
首先,这种方法应该更加干燥。其次,它将您的布局与您碰巧使用的语言分离。最后,它是完全类型安全的并且不使用反射。
首先,创建一个代表语言的类,包装一个Properties
对象。
// Language.scala
class Language(filename: String) {
val properties = new java.util.Properties()
properties.loadFromXML(new FileInputStream(filename))
def apply(key: String) = properties.getProperty(key, s"Key $key not found.")
}
object Language {
val English = new Language("path/to/english.xml")
val Russian = new Language("path/to/russian.xml")
}
还使用Properties XML 格式定义一些翻译:
<!-- path/to/english.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="hello.world">Hello World</entry>
</properties>
<!-- path/to/russian.xml -->
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE properties SYSTEM "http://java.sun.com/dtd/properties.dtd">
<properties>
<entry key="hello.world">привет мир</entry>
</properties>
然后,在渲染时,您可以将您正在使用的语言隐式地放在范围内:
implicit val language: Language = determineLanguage() // Your logic for determining the language you want to use
// Do other things here..
// Render template
Send.txt.MonoEnsure("hi")
然后,在您的模板中,使用如下语言:
@(arg1: Any, arg2: Any)(implicit lang: Language)
<html>
<body>
<p>@lang("hello.world")</p>
</body
</html>
其中,将输出一个显示“Hello World”或“привет мир”的页面,具体取决于选择的语言。
更新:我的第一个建议是使用 Java 的默认属性文件格式,但事实证明它使用不支持西里尔字符的 Latin-1 编码,因此很难与俄语一起使用。因此,我更新了我的答案,改为使用(不幸的是更冗长)Properties XML 格式,它使用 UTF-8 编码,因此支持西里尔字符。