Methods 如何用EL在ZK中实现翻译功能
我的webapp有一个智能的Java转换器,所以我不能在ZK中使用简单的基于标签的i18n。取而代之的是,应该调用我的带有两个参数(key和language)的smart translator方法,但是当前的语言应该从一些webapp范围中获取 有一个EL函数是非常有用的Methods 如何用EL在ZK中实现翻译功能,methods,el,zk,Methods,El,Zk,我的webapp有一个智能的Java转换器,所以我不能在ZK中使用简单的基于标签的i18n。取而代之的是,应该调用我的带有两个参数(key和language)的smart translator方法,但是当前的语言应该从一些webapp范围中获取 有一个EL函数是非常有用的 <textbox value="${x:translate('some.i18n.key')}"/> 并将其用作 <textbox value="${x:translate('qqq',sessionSc
<textbox value="${x:translate('some.i18n.key')}"/>
并将其用作
<textbox value="${x:translate('qqq',sessionScope.get('LANGUAGE'))}"/>
但是,每次编写第二个参数并不是一个好的解决方案。它可以写得短一点,如下所示
<textbox value="${x:translate('qqq',LANGUAGE)}"/>
或者选择一个较短的键而不是语言
,但我对更紧凑的形式感兴趣
是否可以定义这样一个隐式获取第二个参数的函数?或者从EL调用会话/桌面/页面范围中对象的方法?自定义标记库是您需要的解决方案。 它存在于ZK中: 我们将模式与ZK结合使用,而转换是ZK引用进入视图模型的一个领域。为了减少其影响,我们采取了以下措施: 创建了转换器接口:
public interface Translator {
String translate(String key);
// used where the string to be translation includes placeholders
// total_qty=Total qty: {1}
String translate(String key, String... params);
}
和转换器实现:
public class ZKTranslator implements Translator {
@Override
public String translate(String s) {
String translation = Labels.getLabel(s);
if (translation == null)
return s;
return translation;
}
@Override
public String translate(String key, String... params) {
String translation = Labels.getLabel(key, params);
if (translation == null)
return key;
return translation;
}
}
此实现可以引用会话来检索语言,或者(更可取的是)在初始化时将语言传递给ZKTranslator
然后按如下方式使用它。在视图模型中:
public class SomeScreenVM {
private Translator translator;
@Init
public void init() {
// get language from session possibly
translator = new ZKTranslator(); // or new ZKTtanslator(language);
}
public String translate(String s) {
return translator.translate(s);
}
}
在zul文件中:
<window viewModel="@id('vm')" @init('com.example.SomeScreenVM')>
<label value="@load(vm.translate('hello'))"/>
</window>
我可以(错过)使用EL的映射支持来调用对象的非静态单参数方法
首先,我需要一个实现java.util.Map
的translator对象,它可以在其get()
方法中翻译字符串:
public class Translator implements Map<String, String> {
private String language;
public Translator(String language) {
super();
this.language = language;
}
@Override
public String get(Object arg0) {
return translate(arg0.toString(), language);
}
...
}
公共类转换器实现映射{
私有字符串语言;
公共翻译器(字符串语言){
超级();
这种语言=语言;
}
@凌驾
获取公共字符串(对象arg0){
返回translate(arg0.toString(),语言);
}
...
}
然后我可以将翻译器放入桌面范围,并在EL中使用它:
<zscript>
desktopScope.put("tr",new mypackage.Translator(sessionScope.get("language")));
</zscript>
<textbox value="${tr.some_key}"/>
<textbox value="${tr['some.hierarchical.key']}"/>
desktopScope.put(“tr”,新的mypackage.Translator(sessionScope.get(“语言”));
这确实不是一个明确的解决方案,但使使用ZUL文件变得相当简单。感谢您的回答!我的应用程序是一个使用GenericForwardComposer的旧应用程序,没有MVVM。也许我应该切换到MVVM,然后我可以使用这种方法。如果您有选择的话,我强烈建议您切换到MVVM。当然,如果你在处理遗留代码,说起来容易做起来难。谢谢你的回答。不幸的是,我不是JSP标记库的专家,而且相当简短且唯一的文档只描述了公共静态方式。静态方法对您来说不可用吗?如果您需要一个Springbean,那么您可以始终使用servicelocator()模式。我知道有关于它是模式还是反模式的讨论,但除此之外,它可以帮助您。公共静态的问题是我必须提供一个语言参数,但我不想在每次调用时都提供它。所以我需要调用堆栈中的某个存储状态。如何使用自定义taglibs.Sessions.getCurrent始终为您提供当前会话。
<zscript>
desktopScope.put("tr",new mypackage.Translator(sessionScope.get("language")));
</zscript>
<textbox value="${tr.some_key}"/>
<textbox value="${tr['some.hierarchical.key']}"/>