views:

1881

answers:

3

Say you have a standard template with included (parsed) header, body, footer templates.

In the body template a variable like $subject is defined and you want that also displayed in the header template.

In some other template languages like HTML::Mason(perl based) you would evaluate the body template first to pick up the $subject variable but store it's output temporarily in a variable so your final output could end up in the correct order (header, body, footer)

In velocity it would look something like

set ($body=#parse("body.vm"))

parse("header.vm")

${body}

parse("footer.vm")

This however doesn't seem to work, any thoughts on how to do this?

+3  A: 

You can do this using VelocityLayoutServlet which is part of VelocityTools.

This allows you to define a layout for your application -- let's call it application.vm -- in which you can parse in headers, footers etc and declare where the main body content is placed using the screen_content declaration, e.g:

<html>
  <head>
    <title>$subject</title>
  </head>
  <body>
  #parse("header.vm") 
  $screen_content
  #parse("footer.vm") 
  </body>
</html>

VelocityLayoutServlet will evalulate the templates (and, hence, variables) before rendering which allows you to set a $subject variable in your body template, e.g:

#set($subject = "My Subject")
<div id="content">
</div>

More detailed information can be found in the Velocity documentation.

Olly
A: 

If I understand you correctly, you want to have a Velocity variable named $subject interpolated into the header.vm and the body.vm templates. Right now, the variable is defined in the body.vm template, so you cannot refer to it in the earlier template header.vm.

Why don't you abstract out the definition of $subject into its own template snippet, called globals.vm say, then include that in the top-level template. So you'd have:

#parse("globals.vm")
#parse("header.vm")
#parse("body.vm")
#parse("footer.vm")
Dov Wasserman
+3  A: 

Hi,

Either of the two solutions above would work. The VelocityLayoutServlet solution requires an extra package (also from Velocity) called Velocity Tools. I'm partial to this approach (and variants) myself.

A third method is simply to put the #parse within quotes:

set ($body="#parse('body.vm')")

Within a #set, anything in double quotes is evaluated. Strings within single quotes are passed in literally.

Will Glass