Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Xpages:我们如何实现客户端JS代码的本地化?_Javascript_Dojo_Internationalization_Xpages - Fatal编程技术网

Javascript Xpages:我们如何实现客户端JS代码的本地化?

Javascript Xpages:我们如何实现客户端JS代码的本地化?,javascript,dojo,internationalization,xpages,Javascript,Dojo,Internationalization,Xpages,我目前正在开发一个多语言的Xpages驱动的应用程序,使用标准方法通过内部.property资源和资源束本地化静态和动态字符串。在应用程序中,用户可以选择自己喜欢的语言,此决定当前存储在用户配置文档中;我还计划将这些决策存储为浏览器cookie。如果没有用户定义的首选项,浏览器的默认语言将驱动应用程序中使用的区域设置。这适用于所有服务器端元素 现在我必须添加一些客户端脚本,我还需要使用一些本地化字符串。我必须承认,我不知道哪种方法是最好的 主要问题是: 我是否可以使用现有的文件资源/资源包 如果

我目前正在开发一个多语言的Xpages驱动的应用程序,使用标准方法通过内部
.property
资源和
资源束
本地化静态和动态字符串。在应用程序中,用户可以选择自己喜欢的语言,此决定当前存储在用户配置文档中;我还计划将这些决策存储为浏览器cookie。如果没有用户定义的首选项,浏览器的默认语言将驱动应用程序中使用的区域设置。这适用于所有服务器端元素

现在我必须添加一些客户端脚本,我还需要使用一些本地化字符串。我必须承认,我不知道哪种方法是最好的

主要问题是:

  • 我是否可以使用现有的文件资源/资源包
  • 如果是:如何从脚本代码中引用这些资源
  • 如果不是:组织和引用我自己的文件资源的最佳方式是什么
  • 最后:如果我必须自己做这一切:我如何找出哪个语言环境是用户的首选语言环境?如果设置了cookie(见上文),那么这很容易,但是如果我需要参考浏览器的首选项和/或如果用户不允许使用cookie,该怎么办

  • 编辑:我考虑过使用,但我不知道如何实现这样一个自定义插件。

    我使用以下方法:我的所有客户端JavaScript(CSJS)库都存储为数据库设计中的文件资源(参考资料>文件)。在库的代码中,我使用类似EL的符号来标记可翻译部分,例如:

    var text="#{TRLT.TextToTranslate}";
    
    每当我想在XPage上使用库时,我不会直接在XPage的资源中引用它们,而是添加对“Helper XPage”(js.xsp)的引用:


    PS:我不得不修改这里的代码,因为原始版本对我的通用框架有一些依赖,还有一些额外的缓存和错误处理。因此,我不能保证没有输入错误,但原则上它应该可以工作。

    另一种方法是直接在浏览器中读取资源包,并在需要时在JavaScript中引用它。因此,要回答您的主要问题:

  • 是的,但是如果你直接从NSF加载它,它还不能真正使用。我建议创建一个XPage,将其作为JSON对象输出:

    <?xml version="1.0" encoding="UTF-8"?>
    <xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
    
    <xp:this.resources>
        <xp:bundle
        src="/labels_en.properties"
        var="translations">
        </xp:bundle>
    </xp:this.resources>
    
    <xp:this.afterRenderResponse><![CDATA[#{javascript:
    try {
    
     var externalContext = facesContext.getExternalContext();
     var writer = facesContext.getResponseWriter();
     var response = externalContext.getResponse();
    
     response.setContentType("application/json"); 
    
     var jsonOutput = {};
     var keys = translations.keySet();
    
     for (var key in keys) {
       jsonOutput[key] = translations[key];
     }
    
     writer.write(  "var translations = " + toJson(jsonOutput)  ) ;
     writer.endDocument();
    
    } catch (e) {
        print(e);
    }
    }]]>
        </xp:this.afterRenderResponse>
    
    </xp:view>
    

  • 我认为最好的方式是Java方式。在CSJS中,您还可以插入ssjs以从支持的bean中获取标签,这可能对我的博客有所帮助。谢谢你的评论,@FrankvanderLinden。这似乎是维护这些资源的一个非常有用的方法,我将在接下来的几天更权威地阅读它。如果您需要帮助,请告诉我,您有我的博客;-)我使用以下方法:在我的CSJS库中,我使用类似EL的符号来标记可翻译部分,例如
    var text=“#{TRLT.TextToTranslate}”。我没有直接引用html头部中的库,而是引用一个行为类似于JavaScript资源(Content Type=text/JavaScript)的帮助器xpage(js.xsp)。这个XPage加载所有CSJS库,将它们连接起来,并用我也用于服务器端翻译的字典中的字符串替换可翻译部分。我可以发布一些代码,但我想对于您的问题有更简单的解决方案……这听起来很有趣。如果你不在乎伟大的东西,我很想看一些例子!关于内部属性格式还有一个问题:您是使用{“key”:“value”}中的JSON格式,还是引擎本身创建和维护的“key=value”中的XSP标准格式?没关系,我刚刚发现:您正在将标准的“key=value”格式转换为JSON对象,对吗?正确。您可以使用标准的
    key=value
    格式;很难决定我应该接受两个相似的答案中的哪一个;我从上面的@MarkLeusink中选择了一个,因为它稍微simpler@LotharMueller:Mark Leusink的解决方案更易于实施,更适合您想要实现的目标。我不使用这种方法的原因是,我的翻译词典相当大(>5Mb),因为它们也包含HTML模板。在HTML页面上加载那么多内容会导致用户第一次访问页面时加载时间过长。如果您还忘记设置缓存控制头,那么每次用户加载页面时都会发生这种情况。当然,我可以为CSJS翻译创建一个额外的字典,但这使得维护起来更加困难
    importPackage(java.io);
    importPackage(java.lang);
    importPackage(java.util.regex);
    importPackage(javax.servlet.http);
    importPackage(org.apache.commons.io); // AFAIK this package is not installed by default (but generally very helpful)
    
    var i,arr,lng,js,libs,c,s,m,bfr,dct,response,ec,is,os;
    
    //---------------------------- initialize main variables
    ec=facesContext.getExternalContext(); // the external context
    
    lng=(param.lng || "en");  // the language can be provided as url parameter, otherwise use a default
    
    dct=(applicationScope["TRLT_"+lng] || {}); // in my case, the dictionaries (HashMaps) containing the translations are stored in the applicationScope, but of course they can be loaded from anywhere (resource bundles etc.)
    
    libs=(param.libs ? fromJson(param.libs) : ["mylib1.js","mylib2.js"]) // the library names can be provided as url parameter, otherwise use a default
    
    //---------------------------- concatenate all libraries
    js=new StringBuilder();
    for (i=0;i<libs.length;i++) {
        if (s=IOUtils.toString(ec.getResourceAsStream(libs[i]),"UTF-8")) js.append("\n\n"+s);
    }
    js=js.toString();
    
    //---------------------------- search for and replace translateable parts
    m=Pattern.compile("[#$]\\{TRLT\\.([^}]+)\\}").matcher(js);
    bfr=new StringBuffer();
    c=0;
    while (m.find() && c<1e6) {
        c++;
        s=m.group(1);
        m.appendReplacement(bfr,dct[s] || s || "");
    }
    m.appendTail(bfr);
    js=bfr.toString();
    
    //---------------------------- create the response and finalize
    response=ec.getResponse();
    response.setHeader("Cache-Control","max-age="+(60*60*24*365).toFixed(0)); // its important to set the expiration "a bit" into the future to prevent the browser from reloading the js.xsp everytime you reference it on another XPage; in order to force the browser to update the XPage, use versioning (see url parameter "v" in the headTag definition above)
    response.setDateHeader("Expires",new Date().getTime()+(1000*60*60*24*365));
    response.setHeader("Content-Type","text/javascript; name=\"libs.js\"");
    response.setHeader("Content-Disposition","inline; filename=\"libs.js\"");
    
    is=new ByteArrayInputStream(js.getBytes("UTF-8"));
    os=response.getOutputStream();
    IOUtils.copy(is,os);
    is.close();
    os.close();
    facesContext.responseComplete();
    return;
    
    <?xml version="1.0" encoding="UTF-8"?>
    <xp:view xmlns:xp="http://www.ibm.com/xsp/core" rendered="false">
    
    <xp:this.resources>
        <xp:bundle
        src="/labels_en.properties"
        var="translations">
        </xp:bundle>
    </xp:this.resources>
    
    <xp:this.afterRenderResponse><![CDATA[#{javascript:
    try {
    
     var externalContext = facesContext.getExternalContext();
     var writer = facesContext.getResponseWriter();
     var response = externalContext.getResponse();
    
     response.setContentType("application/json"); 
    
     var jsonOutput = {};
     var keys = translations.keySet();
    
     for (var key in keys) {
       jsonOutput[key] = translations[key];
     }
    
     writer.write(  "var translations = " + toJson(jsonOutput)  ) ;
     writer.endDocument();
    
    } catch (e) {
        print(e);
    }
    }]]>
        </xp:this.afterRenderResponse>
    
    </xp:view>
    
    <xp:this.resources>
        <xp:bundle var="translations">
        <xp:this.src><![CDATA[#{javascript:
    var language = "en";        //default language
    
    switch (context.getLocaleString() ) {
    case "nl":
        language = "nl";
        break;
    }
    
    return "/labels_" + language + ".properties";}]]></xp:this.src>
        </xp:bundle>
    </xp:this.resources>