views:

692

answers:

5

After using the Django template language, I really miss being able to do things like this:

{% if condition %}
    <!-- snip -->
{% else %}
    <!-- snip -->
{% endif %}

When I am using JSP, I am stuck doing something like this:

<logic:equal name="something" value="example">
    <!-- snip -->
</logic:equal>
<logic:notEqual name="something" value="example">
    <!-- snip -->
</logic:notEqual>

or:

<% if (condition) { %>
   <!-- snip -->
<% } else { %>
   <!-- snip -->
<% } %>

Is it possible to write a custom tag that supports else and else if, rather than simply having a pair of tags for each check?

If it's not possible, which is the "preferred" style? Scriptlets or multiple tag pairs? At my organization, most people seem to frown upon scriptlets, but I haven't really heard a good reason why simple conditional statements like the ones I've listed are so bad.

A: 

There are conditional tags in the standard tag libraries:

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<c:if ... >

</c:if>

lookup any refererence on jstl.

You can also do this directly in the jsp, although it's a bit frowned upon:

<% if (something) { %>
 ... this will only display if something is true ...
<% } >
Steve B.
I am aware of the jstl tags, do they work with interior else or elseif tags? Or are they still restricted to pairs of tags? It was my impression that they still leave you checking "if condition" then checking "if !condition" for the "else" block.
TM
+2  A: 

The tags in XML come in pairs, one to open one to close. The three elements of the if then else end do not lend to a nice open and close format. The only other way is to use the choose tag as follows:

<c:choose>
  <c:when test="${bean.value == 2}">
    <p>True</p>
  </c:when>
  <c:otherwise>
    <p>False</p>
  </c:otherwise>
</c:choose>

This is the usual way in which to code the if then else structures in jstl.

rmarimon
+2  A: 

The JSTL tags come with a choose tag that works like a multi select.

<c:choose>
    <c:when test="${first condition}">
       whatever
    </c:when>
    <c:when test="${second condition}">
       whatever
    </c:when>
    <c:when test="${third condition}">
       whatever
    </c:when>
    <c:otherwise>
          whatever else
    </c:otherwise>
 </c:choose>
Vincent Ramdhanie
+1  A: 

The above solutions will work (<c:choose> and <c:if>).

If you're interested in writing custom tags to do more or be more "domain specific", they're actually quite easy.

I did a presentation at JavaOne several years ago -- the slides are at http://javadude.com/articles/javaone/index.html (in the first section). There are details on how to write looping and conditional tags. (I did the presentation before the standard tag libs came out, btw)

There's also a really good custom tag tutorial at http://www.orionserver.com/docs/tutorials/taglibs/index.html. It's got a few specifics for orion server, but most of it is very generic.

Scott Stanchfield
I know how to write a custom tag. I wanted to know if it was possible to write a custom tag that wasn't just a start and end tag. Turns out the answer is no.
TM
They're XML tags. What else would be available?
Ian McLaird
You can create a container tag that has many alternatives in it (like the choose mentioned). Take a look at the LayoutManager example in my talk, for example - arbitrary nesting.
Scott Stanchfield
@Ian McLaird: I guess i never understood why they should need to be XML tags. After all, there are plenty of things in most JSPs that make it so that it is no longer a valid XML file.Until rmarimon answered this question, I was unaware that they were restricted to be XML style tags. Frankly I prefer the DTL style where this restriction is NOT in place.
TM
A: 

I don't see any reason why you couldn't write a custom JSP tag that knew to look for the tag in it's bodycontent. It wouldn't be a "best practice", but it would be a pretty clean and intuitive way of doing things.

Dean J