2010-12-19 14 views
4

私はJSF 2.0を使用していて、ページ上の任意のフォルダからすべてのJavaScriptを含めるための手段を探しています、すなわちJSFの1つのフォルダにあるすべてのjavascriptファイルを含めることはできますか?

<h:outputScript library="javascript" name="*.js" target="head" /> 

ような何かをも、可能なこの種のものですか?これを達成するためにJavaコードを使用してカスタムコンポーネントを作成する必要がありますか?あなたの助けのための

おかげで、
セバスチャン・Tromp

+0

私は答えはありませんが、本当に興味深い質問です。これが標準的な機能では不可能な場合は、JSF 2.1の優れた機能要求を行います。 –

答えて

3

いいアイデア。これはJSF APIではサポートされていませんが、カスタムスクリプトレンダラでは理論上可能です。私はそれの周りにやや演奏し、それは確かに可能です。 MultiScriptRendererであるextends ScriptRendererを作成してencodeEnd()を上書きし、name属性に*というワイルドカードが含まれているかどうかを確認してから、このパターンに一致するファイルをリソースフォルダでスキャンして適切に処理します。

ここでキックオフの例です:

package com.example; 

import java.io.File; 
import java.io.FileFilter; 
import java.io.IOException; 
import java.util.Map; 
import javax.faces.component.UIComponent; 
import javax.faces.context.FacesContext; 
import com.sun.faces.renderkit.html_basic.ScriptRenderer; 

public class MultiScriptRenderer extends ScriptRenderer { 

    @Override 
    public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 
     Map<String, Object> attributes = component.getAttributes(); 
     String name = (String) attributes.get("name"); 
     if (name.contains("*")) { 
      String pattern = name.replace(".", "\\.").replace("*", ".*"); 
      String library = (String) attributes.get("library"); 
      File root = new File(context.getExternalContext().getRealPath("/resources/" + (library != null ? library : ""))); 
      for (File file : root.listFiles()) { 
       if (file.getName().matches(pattern)) { 
        attributes.put("name", file.getName()); 
        super.encodeEnd(context, component); 
       } 
      } 
      attributes.put("name", name); // Put original name back. You never know. 
     } else { 
      super.encodeEnd(context, component); 
     } 
    } 
} 

を次のようにfaces-config.xmlに登録(申し訳ありませんが、@FacesRenderer注釈は、それがこの特定のコーナーケースのためにJSF 2.2で修正されるまで仕事に行くされていない、またJSF issue 1748参照)

<render-kit> 
    <renderer> 
     <component-family>javax.faces.Output</component-family> 
     <renderer-type>javax.faces.resource.Script</renderer-type> 
     <renderer-class>com.example.MultiScriptRenderer</renderer-class> 
    </renderer> 
</render-kit> 

Mojarra 2.0.3ではうまく動作します。 *.jsprefix*.jsのようなパターンを使用できます。特定のコード例は、コード定型文を保存するために、特定のJSF実装と密接に結合されています。また、WARをデプロイ時に展開する必要があります。そうしないと、ディレクトリをブラウズすることができなくなります(特定の(古い)サーブレットコンテナのバージョン/コンフィグレーションを除外します)。File#listFiles()でディレクトリをブラウズすることはできません。他のJSFの実装では、代わりにScriptRendererを拡張するか、実装を独立させたい場合は全く新しいものを書く必要があります(かなり単純ですが、ちょっとしたことがあれば標準ScriptRendererのソースを見てください)。

+0

ありがとうございます。その間、私は、いくつかのjavascriptファイルを含める必要性を回避するために何かを見つけましたが、私はこれを間違いなく後で維持しています。 –

+0

すべての緩やかなJSファイルを1つのJSファイルに圧縮(自動)しますか?実際には、HTTPリクエストの量を節約するためにも行われます。 – BalusC

3
私はこれをテストしていないが、ワイルドカードは受け付けていない場合、あなたはバッキングBeanにJavaコードを経由してファイルリストを取得し、使用して頭部にそれらを挿入することができ

あなたはh:outputScriptへの絶対パスを与えることはできませんが、あなたがそれらからプレフィックス(一部preceeds JSFリソースのパス)を抽出する必要があります

<ui:repeat value="#{bean.files}" var="file"> 
    <h:outputScript library="javascript" name="#{file}" target="head" /> 
</ui:repeat> 

注:ようc:forEachまたはui:repeat

関連する問題