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

前端 未结 2 1361
Happy的楠姐
Happy的楠姐 2021-02-10 14:37

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



        
2条回答
  •  遥遥无期
    2021-02-10 15:16

    Nice idea. This is not supported by the JSF API, but it's in theory possible with a custom script renderer. I played somewhat around it and it's indeed possible. Just create a MultiScriptRenderer which extends ScriptRenderer and override encodeEnd() to check if the name attribute contains the * wildcard and then handle accordingly by scanning for files matching this pattern in the resources folder.

    Here's a kickoff example:

    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 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 isn't going to work until it's fixed in JSF 2.2 for this specific corner case, see also JSF issue 1748):

    
        
            javax.faces.Output
            javax.faces.resource.Script
            com.example.MultiScriptRenderer
        
    
    

    Works fine on Mojarra 2.0.3 here. You can use patterns like *.js and prefix*.js. The particular code example is only tight coupled to a specific JSF implementation to save code boilerplate. It also requires that the WAR is expanded on deploy, otherwise browsing the directory by File#listFiles() won't be possible (which thus excludes certain (older) servletcontainer versions/configurations). For other JSF implementations you'll have to extend its ScriptRenderer instead, or write a whole new one if you want to be implementation independent (which should be pretty simple though, just look at standard ScriptRenderer source if you stucks).

提交回复
热议问题