PHP-like output buffering in JSP (letting subtemplates influence the master template)

897 Views Asked by At

In my website I have a master JSP template:

<html>
 <body>
  <nav>...</nav>
  <tiles:insertAttribute name="body" />
  <footer>...</footer>
 </body>
</html>

And multiple page templates:

<p>This is content</p>

Now I'd like the page templates to be able to define some Javascript and CSS includes, so the page templates must be executed before the <head> of the master template.

In PHP I could use output buffering for this:

<? ob_start()
   include $slave;
   $body = ob_get_clean(); ?>
<html>
 <head>
 <? foreach($javascripts as $script) ?>
     <script src="<?=$script?>" />
 <? endforeach ?>
 <body>
  <nav>...</nav>
  <?=$body?>
  <footer>...</footer>
 </body>
</html>

Is there a similar technology available in JSP? Or else another way to achieve what I need? I'm using it in Spring MVC 3 + Apache Tiles

3

There are 3 best solutions below

1
On BEST ANSWER

You could just define an additional attribute (blank by default) in your tiles definition, and insert this attribute inside the head section of the layout page. That's how Tiles is supposed to work.

Or you could use Sitemesh instead of Tiles, which does what you suggest: it uses a filter which buffers the response, and then decorates the response by extracting some of its elements and putting them into a template.

I guess it could be possible to use Sitemesh and Tiles together, but it would become a bit too complex, IMHO.

0
On

I found another solution for my problem.

I've extended my master template with:

<head>
<tiles:insertAttribute name="head" defaultValue="" />
</head>

I have a script which generates the tiles definition XML file (already had). If a subtemplate (say view.jsp) requires extra CSS or Javascript, I'll create a separate file view_head.jsp which contains the correct inclusions, and the script will set the attribute head to that file.

0
On

1) Enable core taglib

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

2) Grap and print content

<c:set var="content">You grab content</c:set>
<c:out value="${content}" />