我的Web应用程序具有一个智能的Java转换器,所以我不能在ZK中使用基于标签的简单i18n。取而代之的是,应该调用具有两个参数的我的智能翻译器方法-键和语言-,但当前语言应从某个webapp范围获取。
具有EL功能将非常有用
<textbox value="${x:translate('some.i18n.key')}"/>
使用给定的String参数和会话中的当前语言代码调用我的智能翻译器方法。
我可以做的是定义一个2参数translate
方法
<?xel-method prefix="x" name="translate"
class="mypackage.Translator"
signature="java.lang.Class translate(java.lang.String,java.lang.String)"?>
并用作
<textbox value="${x:translate('qqq',sessionScope.get('LANGUAGE'))}"/>
但是每次都写第二个参数不是一个好的解决方案。可以写得更短一点,因为
<textbox value="${x:translate('qqq',LANGUAGE)}"/>
或者也许选择一个较短的键而不是LANGUAGE
,但我对更紧凑的格式感兴趣。
是否可以定义这样的函数来隐式获取第二个参数?还是以某种方式从EL调用会话/桌面/页面范围内的对象的方法?
自定义标签库是您需要的解决方案。它存在于ZK中:https://www.zkoss.org/wiki/ZUML_Reference/ZUML/Processing_Instructions/taglib/Custom_Taglib
我们在ZK中使用MVVM模式,而平移是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>