Recently I've decided to get some knowledge about writing custom tags. And there is a problem.
In my web app I use some JSTL tags and in every JSP page I have got an identical piece of code:
<c:if test="${sessionScope.locale == 'locale_ru_RU' or empty sessionScope.locale}" >
<fmt:setBundle basename="locale_ru_RU" />
</c:if>
<c:if test="${sessionScope.locale == 'locale_en_US'}">
<fmt:setBundle basename="locale_en_US" />
</c:if>
As you can see this construction sets correct resource bundle.
So I'd like to know if there is possibility to wrap up this piece of code and use instead of it a single tag (I know there is another way - just put this code in the individual JSP page and use <%@ include %> directive, but I'd like to try a tag)?
As I understand I should someway set body content (inside tag class, not from JSP) and make container to execute it, but I cannot find any examples about it.
What I have got now:
tld:
<?xml version="1.0" encoding="UTF-8"?>
<taglib xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-jsptaglibrary_2_0.xsd"
version="2.0">
<tlib-version>1.0</tlib-version>
<tag>
<name>setLocale</name>
<tag-class>com.test.tags.LocaleBundleTag</tag-class>
<body-content>empty</body-content>
</tag>
</taglib>
and my tag:
public class LocaleBundleTag extends BodyTagSupport {
@Override
public void setBodyContent(BodyContent b) {
try {
b.clear();
b.append("<c:if test=\"${sessionScope.locale == 'locale_ru_RU' or empty sessionScope.locale}\" >");
b.append("<fmt:setBundle basename=\"locale_ru_RU\" />");
b.append("</c:if>");
b.append("<c:if test=\"${sessionScope.locale == 'locale_en_US'}\">");
b.append("<fmt:setBundle basename=\"locale_en_US\" />");
b.append("</c:if>");
} catch (IOException e) {
}
super.setBodyContent(b);
}
}
It compiles, but does nothing correctly.
No, that won't work, because there's no expectation that the body content will then also be processed by the JSP compiler. Rather you would need to implement the fmt:setBundle yourself within your tag.
A JSP Tag file would be easier. Operationally it's not that far removed from the include you mentioned, but it makes refactorings like this really trivial.
I have an extended example here: JSP tricks to make templating easier?