以下のアプローチを使用します。私のクライアントサイドJavaScript(CSJS)ライブラリはすべて、データベース設計(リソース>ファイル)にファイルリソースとして保存されます。私は、例えば、translateable部品をマークするELのような表記を使用したライブラリのコードでは:
var text="#{TRLT.TextToTranslate}";
私はのXPage上のライブラリを使用したいときはいつでも、私は直接のXPageの中でそれらを参照しませんリソースが、その代わりに「ヘルパーのXPage」(js.xsp)への参照を追加します。
<xp:this.resources>
<xp:headTag tagName="script">
<xp:this.attributes>
<xp:parameter name="src" value="js.xsp?lng=#{sessionScope.language}&v=#{applicationScope.versionApp}"/>
<xp:parameter name="type" value="text/javascript"/>
</xp:this.attributes>
</xp:headTag>
</xp:this.resources>
js.xspは、JavaScriptのリソースのように振る舞う:私はのXPage上rendered="false"
を設定し、手動でContent-Type="text/javascript"
で応答を作成しますbeforeRenderResponseイベント。 XPageが呼び出されると、はすべてのCSJSライブラリを読み込み、それらを連結し、サーバ側の翻訳で一般的に使用する辞書に基づいてすべての翻訳を入力します。ここで
はjs.xspのbeforeRenderResponseイベントのコードです:
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;
PS:元のバージョンは、私の一般的なフレームワークにはいくつかの依存性だけでなく、いくつかの追加を持っているので、私はここで紹介するコードを変更する必要がありましたキャッシングとエラー処理。したがって、私はタイプミスがないことを保証することはできませんが、原則として動作するはずです。
:
コメントのおかげで@FrankvanderLinden。それらのリソースを維持するための非常に有用なアプローチであるように見える、私はそれを次の数日にわたってより強く読むだろう –
私はあなたに助けが必要であることを私に知らせる、あなたは私のブログを持っている;-) –