2014-02-20 35 views
1

我正在翻译一个Web应用程序,而且事情通常会与wicket一起顺利进行:消息和属性文件。但Wicket总是希望有一个查找字符串的组件。
如何翻译(中IConverterIChoiceRenderer即实现)转换器和渲染器不能够访问他们的任何方法检票组件?如何国际化Wicket中的转换器或渲染器?

到目前为止,我发现了一个办法 - Application.get().getResourceSettings().getLocalizer().getString(key, null) - 但我不得不做出字符串“全球性”,即与应用类相关联。这对分离和重用来说并不好。我怎样才能做得更好?

回答

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),所以属性现在可以附加到转换器类。

似乎工作:)

+0

有趣的方式。我也在考虑这个问题,但看起来很尴尬,因为你必须每次投射本地化器,或者你必须介绍一些类似于MyConverter的东西。无论如何,它看起来并不那么糟糕.... –

0

如果我明白你的问题......

可以使用基于包的属性,这意味着,如果你把你的钥匙/值到包中的属性文件“package.properties”。该包下的任何子包的每个本地化资源都会返回与所请求的键关联的值,直到您在另一个属性文件中覆盖它为止。

的文件名是 'package.properties' 在检票口前1.6.x版和检票1.6+

'wicket-package.properties' 见

https://cwiki.apache.org/confluence/display/WICKET/Migration+to+Wicket+6.0#MigrationtoWicket6.0-package.propertiesrenamedtowicket-package.properties

但是它只是对及部件,在外界及部件(当组件参数为空),也可以使用:

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

+0

AFAIK这不会Application.get()工作。getResourceSettings()。getLocalizer()的getString(键,NULL)。它从层次结构中的包开始处理组件,然后爬到父包。 IE浏览器。它必须知道什么时候开始查找包的层次结构,但是当你告诉该组件为空时,它不会。 –

+0

那么,我将如何从基于包的属性获取字符串? – aditsu

+0

是的,你是对的,它不可能使用getString(key,null)。在这种情况下,全局属性文件位于应用程序类之后命名的属性文件中,例如WicketApplication,我在https://repo.twinstone.org/projects/WISTF/repos/wicket-examples-6.x/browse上做了一个小例子 –

2

完整的例子,我想你应该创造你自己的方式如何实现这一目标。在这里,在我目前的项目,我们注册了自己IStringResourceLoader这样的:

IStringResourceLoader stringResourceLoader = new OurOwnResourceLoaderImpl();    
Application.get().getResourceSettings().getStringResourceLoaders().add(stringResourceLoader); 

然后例如在IChoiceRenderer我们只需要调用Application.get()getLocalizer()的getString( “钥匙”,NULL)。

在我们的IStringResourceLoader中,我们正在根据自己的约定寻找包含一些字符串模式的包(属性文件)。

或者,你可以注册本地化包(即。属性文件)通过org.apache.wicket.resource.loader.BundleStringResourceLoader分布在Application#init的库中。

Afaik没有标准的方法来做到这一点,所以它取决于你选择什么样的路径。

更新时间:

我发现了另一个解决方案资料库/分机如何注册它自己的定位本身,所以你不必触摸应用程序初始化#或创建自己的IStringResourceLoaders。

有预先注册的字符串资源加载org.apache.wicket.resource.loader.InitializerStringResourceLoader(见售票窗口默认IResourceSetting实现即ResourceSetting,它的构造。),它采用检票口的初始化机制 - 见IInitializer的javadoc - 基本上你添加wicket.properties文件在您的罐子类根和内部文件存在(即它是在默认/无包装):

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)

+0

那么,这样的属性文件仍然是全球注册的权利?它们可以位于不同的文件中,但仍然与整个Web应用程序相关联。 – aditsu

+0

那么这取决于你将使用什么方式。当你调用Localizer#getString(...)时,它试图询问每个注册的IStringResourceLoader是否存在本地化文本。如果您将使用org.apache.wicket.resource.loader.BundleStringResourceLoader,那么它的注册方式与您的应用程序本地化文件相同。 –

+0

是的,如果我调用'getString(key,null)',那么我认为它将是全局的,因为没有任何特定的东西(例如类)要附加到。但我找到了一个不同的解决方案,查看我刚发布的答案。 IInitializer的东西很有趣,我想我可以结合这些想法。 – aditsu