Question

Embedded custom-tag in dynamic content (nested tag) not rendering.

I have a page that pulls dynamic content from a javabean and passes the list of objects to a custom tag for processing into html. Within each object is a bunch of html to be output that contains a second custom tag that I would like to also be rendered. The problem is that the tag invocation is rendered as plaintext.

An example might serve me better.

1 Pull information from a database and return it to the page via a javabean. Send this info to a custom tag for outputting.

<jsp:useBean id="ImportantNoticeBean" scope="page" class="com.mysite.beans.ImportantNoticeProcessBean"/>  <%-- Declare the bean --%>
<c:forEach var="noticeBean" items="${ImportantNoticeBean.importantNotices}"> <%-- Get the info --%>
    <mysite:notice importantNotice="${noticeBean}"/> <%-- give it to the tag for processing --%>
</c:forEach>

this tag should output a box div like so

*SNIP* class for custom tag def and method setup etc
out.println("<div class=\"importantNotice\">");
out.println("   " + importantNotice.getMessage());
out.println("   <div class=\"importantnoticedates\">Posted: " + importantNotice.getDateFrom() + " End: " + importantNotice.getDateTo()</div>");
out.println("   <div class=\"noticeAuthor\">- " + importantNotice.getAuthor() + "</div>");
out.println("</div>");
*SNIP*

This renders fine and as expected

<div class="importantNotice">
    <p>This is a very important message. Everyone should pay attenton to it.</p>
    <div class="importantnoticedates">Posted: 2008-09-08 End: 2008-09-08</div>
    <div class="noticeAuthor">- The author</div>
</div>

2 If, in the above example, for instance, I were to have a custom tag in the importantNotice.getMessage() String:

*SNIP* "This is a very important message. Everyone should pay attenton to it. <mysite:quote author="Some Guy">Quote this</mysite:quote>" *SNIP*

The important notice renders fine but the quote tag will not be processed and simply inserted into the string and put as plain text/html tag.

<div class="importantNotice">
    <p>This is a very important message. Everyone should pay attenton to it. <mysite:quote author="Some Guy">Quote this</mysite:quote></p>
    <div class="importantnoticedates">Posted: 2008-09-08 End: 2008-09-08</div>
    <div class="noticeAuthor">- The author</div>
</div>

Rather than

<div class="importantNotice">
    <p>This is a very important message. Everyone should pay attenton to it. <div class="quote">Quote this <span class="authorofquote">Some Guy</span></div></p>    // or wahtever I choose as the output
    <div class="importantnoticedates">Posted: 2008-09-08 End: 2008-09-08</div>
    <div class="noticeAuthor">- The author</div>
</div>

I know this has to do with processors and pre-processors but I am not to sure about how to make this work.

Was it helpful?

Solution

Just using

<bodycontent>JSP</bodycontent>

is not enough. You should do soimething like

JspFragment body = getJspBody(); 
StringWriter stringWriter = new StringWriter(); 
StringBuffer buff = stringWriter.getBuffer(); 
buff.append("<h1>"); 
body.invoke(stringWriter); 
buff.append("</h1>"); 
out.println(stringWriter);

to get inner tags rendered (example is for SimpleTag doTag method).

However, in the question's code I see that inner tag is comming from a string which is not rendered as a part of JSP, but just some random string. I do not think you can force JSP translator to parse it.

You can use regexp in your case or try to redesign your code in a way to have a jsp like this:

<jsp:useBean id="ImportantNoticeBean" scope="page class="com.mysite.beans.ImportantNoticeProcessBean"/>
<c:forEach var="noticeBean" items="${ImportantNoticeBean.importantNotices}">
    <mysite:notice importantNotice="${noticeBean}">
        <mysite:quote author="Some Guy">Quote this</mysite:quote>
        <mysite:messagebody author="Some Guy" />
    </mysite:notice>
</c:forEach>

I whould go with regexp.

OTHER TIPS

I would be inclined to change the "architecture of your tagging" in that the data you wish to achieve should not be by tag on the inside of the class as it is "markup" designed for a page(though in obscurity it is possible to get the evaluating program thread of the JSP Servlet engine).

What you would probably find better and more within standard procedure would be using "cooperating tags" with BodyTagSupport class extension and return EVAL_BODY_BUFFERED in doStartTag() method to repeat process the body and/or object sharing such as storing retrived data in the application hierarchy of the session or on the session for the user.

See oracle j2ee custom tags tutorial for more information.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top