Search code examples
jsffaceletscomposition

How to use Facelets composition with files from another context


I have an application that use composition (for page templates). But we think in create a web-application (war) to host all templates shared by all applications in the same host of all applications.

How I can include a template from another context? At this time I use import from http request. But it's sounds like bad.

<ui:composition template="http://localhost:8080/templates/layout/foo.xhtml">

I'm using JBoss Seam 2.x with JSF 1.


Solution

  • Note that this is to be done differently in JSF 2.x Facelets, see this answer for detail.

    This is possible with a custom Facelets resource resolver. I would only not resolve them by HTTP, but just from the classpath. Just package the shared templates in for example the /META-INF/resources folder of the JAR file and drop the resolver class in the same JAR. Finally distribute this JAR among all webapps.

    package com.example;
    
    import java.net.URL;
    
    import com.sun.facelets.impl.DefaultResourceResolver;
    
    public class FaceletsResourceResolver extends DefaultResourceResolver {
    
        private String basePath;
    
        public FaceletsResourceResolver() {
            this.basePath = "/META-INF/resources"; // TODO: Make configureable?
        }
    
        public URL resolveUrl(String path) {
            URL url = super.resolveUrl(path); // Resolves from WAR.
    
            if (url == null) {
                url = getClass().getResource(basePath + path); // Resolves from JAR.
            }
    
            return url;
        }
    
    }
    

    Register it in web.xml as follows:

    <context-param>
        <param-name>facelets.RESOURCE_RESOLVER</param-name>
        <param-value>com.example.FaceletsResourceResolver</param-value>
    </context-param>