我正在翻译一个Web应用程序,事情通常与wicket:消息和属性文件一起顺利进行。但Wicket总是希望有一个组件来查找字符串
如何翻译无法访问其方法中任何Wicket组件的转换器和渲染器(即IConverter
和IChoiceRenderer
的实现)?
到目前为止,我找到了一种方法 - Application.get().getResourceSettings().getLocalizer().getString(key, null)
- 但我必须使字符串“全局”,即与应用程序类相关联。这对于分离和重用来说并不好。我怎样才能做得更好?
答案 0 :(得分:2)
我认为你应该发明自己的方式来实现这一目标。在我当前的项目中,我们注册了我们自己的IStringResourceLoader,如下所示:
IStringResourceLoader stringResourceLoader = new OurOwnResourceLoaderImpl();
Application.get().getResourceSettings().getStringResourceLoaders().add(stringResourceLoader);
然后例如在IChoiceRenderer中我们只调用Application.get()。getLocalizer()。getString(“key”,null)。
在我们的IStringResourceLoader中,我们正在根据自己的约定寻找带有一些字符串模式的bundle(属性文件)。
或者您可以通过org.apache.wicket.resource.loader.BundleStringResourceLoader在Application#init中注册分发在库的jar中的本地化包(即属性文件)。
Afaik没有标准的方法可以做到这一点因此取决于你选择的路径。
<强>更新强>
我找到了另一个解决方案,你的库/扩展可以自己注册它自己的本地化,所以你不需要触摸Application#init或创建自己的IStringResourceLoaders。
有预先注册的字符串资源加载器org.apache.wicket.resource.loader.InitializerStringResourceLoader(参见wickets默认的IResourceSetting实现,即ResourceSetting和它的构造函数),它使用wicket的Initializer机制 - 请参阅IInitializer javadoc - 基本上你添加了wicket.properties文件在你的jar类根目录(即它在默认/无包中)和内部文件中有:
initializer=i.am.robot.MyInitilizer
然后i.am.robot.MyInitilizer:
public class MyInitializer implements IInitializer {
/**
* @param application
* The application loading the component
*/
void init(Application application) {
// do whatever want
}
/**
* @param application
* The application loading the component
*/
void destroy(Application application) {
}
}
现在您使用与IInitializer实现相同的包和名称创建本地化包(在我们的示例中为MyInitializer)
答案 1 :(得分:1)
我想我找到了另一种方式......
我注意到IStringResourceLoader
还有一个方法String loadStringResource(Class<?> clazz, String key, Locale locale, String style);
(还有一个更新的Wicket版本的变量参数),它不需要组件。 clazz
应该是一个组件类,但是......它实际上不得 :()
我能够用新方法实现我自己的class MyLocalizer extends Localizer
getString(String key, Class<?> cl, IModel<?> model, Locale locale, String defaultValue)
其工作方式与方法类似
getString(String key, Component component, IModel<?> model, String defaultValue)
但直接使用该类而不是组件。它仍然使用相同的属性缓存和资源加载器。
然后我写了一个abstract class MyConverter implements IConverter
,它有一个MyLocalizer getLocalizer()
和一些getString
方法,比如Component
类。基本上它是getLocalizer().getString(key, getClass(), model, locale, defaultValue)
,因此属性现在可以附加到转换器类。
似乎工作:)
答案 2 :(得分:0)
如果我理解你的问题......
您可以使用基于包的属性,这意味着您将键/值放入包中的属性文件“package.properties”中。该包下任何子包的每个本地化资源都会返回与请求的键关联的值,直到您在另一个属性文件中覆盖它为止。
文件名在1.6.x之前的Wicket中为' package.properties ',在Wicket 1.6 +中为 wicket-package.properties '
见
然而,它只适用于componet,在componet之外(当component参数为null时),可以使用:
WicketApplication.properties (WebApplication类 WicketApplication.class ,此属性文件位于同一个包中。)
applicationGlobalProperty=My Global Localized Property
wicket-package.properties (基于包,将其放在与页面相同的包中)
localText=Localized text: A local component text based on wicket-package.properties
LocalizedPage.html (标记模板)
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Localized Page</title>
</head>
<body xmlns:wicket="http://wicket.apache.org">
<div>
<div>
<h2>Texts</h2>
<div>
<wicket:message key="localText"/> <br/>
<span wicket:id="localizedLabel"></span>
</div>
</div>
</div>
</body>
</html>
LocalizePage.java (代码)
public class LocalizedPage extends WebPage {
private static final long serialVersionUID = 1L;
public LocalizedPage() {
super();
}
@Override
protected void onInitialize() {
super.onInitialize();
add(new Label("localizedLabel", new AbstractReadOnlyModel<String>() {
private static final long serialVersionUID = 1L;
@Override
public String getObject() {
return WicketApplication.get().getResourceSettings().getLocalizer().getString("applicationGlobalProperty", null);
}
}));
}
}
请参阅https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-6.x/browse
上的完整示例