Using Facelets to Conditionally Include Scripts
I am working on a large Java project that utilizes JSF and facelets, and am learning a bit more about how they work. I am using a template that is shared by all pages on the site, which also includes JavaScript files required by almost all pages on the site. I was looking for a clean way to exclude the base JavaScript files on the few pages that didn't require them, and this is what I came up with.
Basically, I found that the ui:insert tag can be filled with default content, so I created a ui:insert section and called it 'baseScripts'. This section contains references to the common JavaScript files used throughout the site. Here is my template:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets">
<ui:insert name="baseScripts>
<script type="text/javascript" src="/javascript/jQuery/jquery.js"></script>
<script type="text/javascript" src="/javascript/common.js"></script>
</ui:insert>
<ui:insert name="additionalScripts">
</ui:insert>
<head>
<title>My Title</title>
<link href="../../style/MyStyles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<ui:insert name="bodyContent"> </ui:insert>
</body>
</html>
Because the 'baseScript' ui:insert contains the base JavaScript references, we do not need to define those references, they are included automatically as long as a page utilizes this template. But, what if we want to exclude those references ?
In this case, we can utilize the ui:define tag, which will in essence override our default content. If our page does not require these base JavaScript files, we should keep it clean and not reference them...
Here is an example file utilizing our template and overriding the base script list. Imagine that this page doesn't require the jQuery library or the common.js file, but it does require another file, special.js, which has no dependencies:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html">
<body>
<ui:composition template="myTemplate.xhtml">
<ui:define name=”baseScripts"></ui:define>
<ui:define name="additionalScripts">
<script type="text/javascript" src="/javascript/special.js"></script>
</ui:define>
<ui:define name="bodyContent">
<div>
<p>Hello</p>
</div>
</ui:define>
</ui:composition>
</body>
</html>
This technique is pretty simple, but it could be useful when you need to differentiate a page from the common case -- where something that is needed by the majority of pages is unnecessary.