4

For example, a user will be rendered throughout my application as

<div class="user">
  <p class="username">${user.name}</p>
  <p class="karma">${user.karma}</p>
  <img src="/users/${user.id}"/>
</div>

How can I reuse this code block?

Note - my code is running within a tag, so I can't use tags for this (or any JSP) otherwise I get a Scripting elements are disallowed here error.

Edit

I'm trying to use a tag file, but getting PropertyNotFoundException.

This is my tag file called 'user.tag':

<%@tag description="User" pageEncoding="UTF-8" %>

<a href="../user/showUser.do?userId=${user.id}">
    <p>${user.name}</p>
    <img class='avatar' src='${user.avatarUrl}' alt=""/>
</a>

And usage inside a jsp:

Where job.poster is a java bean with id, name, and avatarUrl properties. If I add

<%@attribute name="user" %>

to the tag file, then I get an exception

Property 'id' not found on type java.lang.String
ripper234
  • 222,824
  • 274
  • 634
  • 905

5 Answers5

7

Since JSP 2.0, there is yet another kind of tags: Tag files. Tag files are JSP custom tags written as a JSP template itself, which seems to be what you want.

http://fforw.de/post/creating-jsp-layouts-with-page-tags/ shows how to use such a tag file as general layout solution. Using them as component should be even easier.

fforw
  • 5,391
  • 1
  • 18
  • 17
2

You should be able to use tag files within tag files; this works for me in a JSP 2.2 container:

<%-- mytag.tag --%>
<%@tag description="demo code" pageEncoding="UTF-8"%>
<%@taglib prefix="cust" tagdir="/WEB-INF/tags" %>
<%@attribute name="message"%>
<cust:mytag2 message="${message}" /><%-- uses mytag2.tag --%>

If that fails, you can use the include directive: <%@include file="/WEB-INF/jspf/fragment.jspf" %>

Note that the spec says about tags:

Directive Available? Interpretation/Restrictions
======================================================================
page      no         A tag file is not a page. The tag directive must
                     be used instead. If this directive is used in a
                     tag file, a translation error must result.

So, fragment.jspf must not have a any elements that are not supported in tags, including a page directive.

McDowell
  • 107,573
  • 31
  • 204
  • 267
1

For the example you have given it sounds like some templating framework is needed, to display the user badge on each screen. At its simplest level this may just be a jsp:include which always includes your "UserBadge.jsp".

If you are running on a web framework e.g. JSF you may use Facelet templates or write a custom component for this. So the answer depends on what framework you have. Breaking it down to just JSP and JSTL - the included JSP or a javax.servlet.jsp.tagext.Tag would certainly reduce the duplication.

Always be careful to follow the DRY Principle... Don't Repeat Yourself!

planetjones
  • 12,469
  • 5
  • 50
  • 51
  • I would like to use a tag for this, but not sure exactly how to define it. Could you point me towards a code sample? – ripper234 May 20 '11 at 12:47
0

I feel sometimes creating a .tag file is overkill (especially if it's only for one page), and I've wanted what you describe for years, so I wrote my own, simple solution. See here: https://stackoverflow.com/a/25575120/1607642

Community
  • 1
  • 1
-1

Why don't you use a custom tag or jsp functions.

Thanks,

Ramesh PVK
  • 15,200
  • 2
  • 46
  • 50