Is it possible to include all javascripts files from the same folder in JSF?

I am using JSF 2.0 and I am looking for a way to include all javascripts from a given folder on a page, i.e. do something like

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

Is this possible? Should I write a custom component using java code for this?

Thank you for your help,
Sebastian Tromp

+4
source share
2 answers

A good idea. This is not supported by the JSF API, but it is theoretically possible using a special script renderer. I played around a bit, and it's really possible. Just create a MultiScriptRenderer that extends ScriptRenderer and override encodeEnd() to check if the name attribute contains the * template, and then process it accordingly by scanning the files matching that template in the resource folder.

Here is an example run:

 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); } } } 

Register it in faces-config.xml as follows (Sorry, @FacesRenderer annotation will not work until it is fixed in JSF 2.2 for this specific corner case, see also 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> 

Works great on Mojarra 2.0.3. You can use templates such as *.js and prefix*.js . A specific code example is only associated with a specific JSF implementation for storing a code template. It also requires the WAR to expand upon deployment, otherwise browsing the directory using File#listFiles() will be impossible (which thus excludes some (older) versions / configurations of servlet containers). For other JSF implementations, you will need to expand its ScriptRenderer or write a completely new one if you want to be implementation independent (which should be pretty simple, just look at the standard ScriptRenderer source if you are stucks).

+3
source

I have not tested this, but if wildcards are not accepted, you can get the list of files via java code in the backup bean and paste them into the head using c:forEach or ui:repeat , for example:

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

Note that you cannot give absolute paths to h:outputScript , but you must extract the prefix from them (the part preceding the JSF resource path).

+3
source

Source: https://habr.com/ru/post/1332653/


All Articles