A Simple Alternative to the MyFaces ExtensionFilter
The MyFaces ExtensionFilter has two purposes:
For the first purpose, the filter works just fine. For the second purpose, however, the filter must cache the entire response and parse it to find the <head> component. The Tomahawk web page warns that this uses extra memory, but I think the side effects are slightly underexaggerated. The problems I encountered were:
Basically it comes down to performance. I can see that the MyFaces team have delegated the job of adding resources via the AddResource interface so I could theoretically implement my own version to work around these issues. That looked way too hard, so I came up with a simpler solution.
I noticed that, actually, you can just hard-code the MyFaces resources in the head section and the components work just fine. The filter is then only used for retrieving these resource since there is no need to inject them into the <head>. With Facelets, you can pass a <ui:param> to your master template to indicate whether or not you need certain resources on a page. Here is an example.
Filter configuration (web.xml):
<!-- MyFaces extension filter (not mapped to FacesServlet)--> <filter> <filter-name>MyFacesExtensionsFilter</filter-name> <filter-class>org.apache.myfaces.webapp.filter.ExtensionsFilter</filter-class> </filter> <filter-mapping> <filter-name>MyFacesExtensionsFilter</filter-name> <url-pattern>/faces/myFacesExtensionResource/*</url-pattern> </filter-mapping>
Master template head section:
<ui:decorate template="master.xhtml"> <ui:param name="useMyFacesTabs" value="true"/> <t:panelTabbedPane> <t:panelTab>Tab 1</t:panelTab> <t:panelTab>Tab 2</t:panelTab> </t:panelTabbedPane> </ui:decorate>
Pretty simple really, but you'd be suprised how long it took me to come up with this idea (hint: it's in the order of days - possibly weeks). I got buried way too deep in interfaces, components and filters.
If you're using JSP you could do something similar, except your conditions might be more complicated since you don't have the luxury of master/client templates (unless you are using Tiles).
This is a problem I believe can be tracked back to the condition that the component tree be built and rendered during the same phase (mostly to accomodate JSP). With separate build and render phases, you could have a <h:head> component which other components could add resources to as they are created during the tree build.
Roger Keays is an artist, an engineer, and a student of life. Since he left Australia in 2009, he has been living as a digital nomad in over 40 different countries around the world. Roger is addicted to surfing. His other interests are music, psychology, languages, and finding good food. Click here to subscribe to his weekly blog, or stalk him on Facebook and Twitter.