You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Kelvin Tan <ke...@myangel.com> on 2001/05/26 04:09:17 UTC

Re: [Off-Topic] Help with Velocity

Sorry about it. :)

I wasn't used to the time it took for my post to get out to the list. It had
actually been 5 hours since I posted it, and I kinda needed it in a hurry.
Guess was used to the lightning-fast response of jakarta-commons and
turbine-users...oops

Anyhow here's the classes.

The Item class.
public class Item
{
 public Item()
 {
 }
 public String getThumbnail()
 {
  return Thumbnail;
 }
 public void setThumbnail(String s)
 {
  Thumbnail = s;
 }
 public String getNumber()
 {
  return Number;
 }
 public void setNumber(String s)
 {
  Number = s;
 }
 private String Thumbnail;
 private String Number;
}

In the VelocityServlet extender class

private static Vector ItemList = new Vector();
protected Context createContext(HttpServletRequest req, HttpServletResponse
res)
  {
  VelocityContext context = new VelocityContext();
processFeed();
  return context;
 }

private void processFeed()
{
//There's some other logic here
while (true)
{
Item csi = new Item();
csi.setThumbnail(strbf.toString());
csi.setNumber(strbf.toString());
    if (csi.getThumbnail()!=null)
    {
    //Adds itself to the Collection of Items
     ItemList.add(csi);
    }
}

public Template handleRequest( Context context )
    {
        context.put("ItemList", ItemList);
        Template template = null;
        try
        {
            template =  getTemplate("mytemplate.vm");
        }
        catch( ResourceNotFoundException rnfe )
        {
          // couldn't find the template
        }
        catch( ParseErrorException pee )
        {
          // syntax error : problem parsing the template
        }
        catch( Exception e )
        {}
        return template;
    }

 protected void requestCleanup(HttpServletRequest req, HttpServletResponse
res, Context context)
 {
  ItemList.clear();
 }


And the template goes
#foreach($csi in $ItemList)
$csi.Thumbnail <br>
$csi.Number <br>
#end

and also have tried
#foreach($csi in $ItemList)
$csi.getThumbnail() <br>
$csi.getNumber() <br>
#end

The $csi.Thumbnail works now (not initially) but $csi.Number and
$csi.getNumber() doesnt. Any clue?

Thanks in advance...and sorry again.

----- Original Message -----
From: "Geir Magnusson Jr." <ge...@optonline.net>
To: <tu...@jakarta.apache.org>
Sent: Friday, May 25, 2001 9:12 PM
Subject: Re: [Off-Topic] Help with Velocity


> Kelvin Tan wrote:
> >
> > Hi, sorry to post on Turbine-users, but I kinda need help and
Velocity-users
> > isn't really forthcoming.
>
> Not to pile on (Kaspar already said this...) but you just posted
> recently...
>
> I responded on velocity, although the message hasn't shown up yet -
> maybe you'll get this one faster, but please take this back to vel-user
> or vel-dev.
>
> The upshot is
>
> 1) make sure that gettter/setter methods are declared public.  Velocity
> won't transgress access declarations.
>
> 2) send the skeleton of the class (no method body code) and we can take
> a look.
>
> geir
>
> --
> Geir Magnusson Jr.                           geirm@optonline.net
> System and Software Consulting
> Developing for the web?  See http://jakarta.apache.org/velocity/
> "still climbing up to the shoulders..."
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: turbine-user-unsubscribe@jakarta.apache.org
> For additional commands, e-mail: turbine-user-help@jakarta.apache.org
>


Re: [Off-Topic] Help with Velocity

Posted by Kelvin Tan <ke...@myangel.com>.
You're absolutely right. It compiled and ran perfectly.

It's probably something to do with my logic.Will take another look at it.

Thanks again. :)
----- Original Message -----
From: "Geir Magnusson Jr." <ge...@optonline.net>
To: <ve...@jakarta.apache.org>
Sent: Saturday, May 26, 2001 11:21 AM
Subject: Re: [Off-Topic] Help with Velocity


> here's my example. it worked fine :
>
> I took the SampleServlet.java example in examples/servlet_example1 in
> the 1.1-rc1 distro and replaced the handleRequest() with the following :
>
>  public Template handleRequest( Context context )
>     {
>
>         Vector v = new Vector();
>
>         for (int i = 0; i < 10; i++)
>         {
>             Item item = new Item();
>
>             item.setNumber( String.valueOf( i ) );
>
>             v.addElement( item );
>         }
>
>         context.put("theList", v );
>
>         Template outty = null;
>
>         try
>         {
>             outty =  getTemplate("kelvin.vm");
>         }
>         catch( Exception e )
>         {
>             System.out.println("Error " + e);
>         }
>         return outty;
>     }
>
> where Item.java :
>
> public class Item
> {
>     private String Thumbnail;
>     private String Number;
>
>     public Item()
>     {
>     }
>
>     public String getThumbnail()
>     {
>         return Thumbnail;
>     }
>     public void setThumbnail(String s)
>     {
>         Thumbnail = s;
>     }
>     public String getNumber()
>     {
>         return Number;
>     }
>     public void setNumber(String s)
>     {
>         Number = s;
>     }
> }
>
> and the template kelvin.vm
>
> <html><body>
>
> Hello from Kelvin
>
> #foreach($item in $theList)
>   $item.number<br>
> #end
>
> #foreach($item in $theList)
>   $item.getNumber()
> #end
>
> #foreach($item in $theList)
>   $item.Number
> #end
>
> </body></html>
>
> I then threw the Item.class and KelvinServlet.class into my
> WEB-INF/class directory, threw kelvin.vm into the templates directory,
> and gave it a whirl...
>
> all worked fine.
>
> geir
>
>
> Kelvin Tan wrote:
> >
> > Sorry about it. :)
> >
> > I wasn't used to the time it took for my post to get out to the list. It
had
> > actually been 5 hours since I posted it, and I kinda needed it in a
hurry.
> > Guess was used to the lightning-fast response of jakarta-commons and
> > turbine-users...oops
> >
> > Anyhow here's the classes.
> >
> > The Item class.
> > public class Item
> > {
> >  public Item()
> >  {
> >  }
> >  public String getThumbnail()
> >  {
> >   return Thumbnail;
> >  }
> >  public void setThumbnail(String s)
> >  {
> >   Thumbnail = s;
> >  }
> >  public String getNumber()
> >  {
> >   return Number;
> >  }
> >  public void setNumber(String s)
> >  {
> >   Number = s;
> >  }
> >  private String Thumbnail;
> >  private String Number;
> > }
> >
> > In the VelocityServlet extender class
> >
> > private static Vector ItemList = new Vector();
> > protected Context createContext(HttpServletRequest req,
HttpServletResponse
> > res)
> >   {
> >   VelocityContext context = new VelocityContext();
> > processFeed();
> >   return context;
> >  }
> >
> > private void processFeed()
> > {
> > //There's some other logic here
> > while (true)
> > {
> > Item csi = new Item();
> > csi.setThumbnail(strbf.toString());
> > csi.setNumber(strbf.toString());
> >     if (csi.getThumbnail()!=null)
> >     {
> >     //Adds itself to the Collection of Items
> >      ItemList.add(csi);
> >     }
> > }
> >
> > public Template handleRequest( Context context )
> >     {
> >         context.put("ItemList", ItemList);
> >         Template template = null;
> >         try
> >         {
> >             template =  getTemplate("mytemplate.vm");
> >         }
> >         catch( ResourceNotFoundException rnfe )
> >         {
> >           // couldn't find the template
> >         }
> >         catch( ParseErrorException pee )
> >         {
> >           // syntax error : problem parsing the template
> >         }
> >         catch( Exception e )
> >         {}
> >         return template;
> >     }
> >
> >  protected void requestCleanup(HttpServletRequest req,
HttpServletResponse
> > res, Context context)
> >  {
> >   ItemList.clear();
> >  }
> >
> > And the template goes
> > #foreach($csi in $ItemList)
> > $csi.Thumbnail <br>
> > $csi.Number <br>
> > #end
> >
> > and also have tried
> > #foreach($csi in $ItemList)
> > $csi.getThumbnail() <br>
> > $csi.getNumber() <br>
> > #end
> >
> > The $csi.Thumbnail works now (not initially) but $csi.Number and
> > $csi.getNumber() doesnt. Any clue?
> >
> > Thanks in advance...and sorry again.
> >
> > ----- Original Message -----
> > From: "Geir Magnusson Jr." <ge...@optonline.net>
> > To: <tu...@jakarta.apache.org>
> > Sent: Friday, May 25, 2001 9:12 PM
> > Subject: Re: [Off-Topic] Help with Velocity
> >
> > > Kelvin Tan wrote:
> > > >
> > > > Hi, sorry to post on Turbine-users, but I kinda need help and
> > Velocity-users
> > > > isn't really forthcoming.
> > >
> > > Not to pile on (Kaspar already said this...) but you just posted
> > > recently...
> > >
> > > I responded on velocity, although the message hasn't shown up yet -
> > > maybe you'll get this one faster, but please take this back to
vel-user
> > > or vel-dev.
> > >
> > > The upshot is
> > >
> > > 1) make sure that gettter/setter methods are declared public.
Velocity
> > > won't transgress access declarations.
> > >
> > > 2) send the skeleton of the class (no method body code) and we can
take
> > > a look.
> > >
> > > geir
> > >
> > > --
> > > Geir Magnusson Jr.                           geirm@optonline.net
> > > System and Software Consulting
> > > Developing for the web?  See http://jakarta.apache.org/velocity/
> > > "still climbing up to the shoulders..."
> > >
> > > ---------------------------------------------------------------------
> > > To unsubscribe, e-mail: turbine-user-unsubscribe@jakarta.apache.org
> > > For additional commands, e-mail: turbine-user-help@jakarta.apache.org
> > >
>
> --
> Geir Magnusson Jr.                           geirm@optonline.net
> System and Software Consulting
> Developing for the web?  See http://jakarta.apache.org/velocity/
> "still climbing up to the shoulders..."
>


Re: [Off-Topic] Help with Velocity

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
here's my example. it worked fine :

I took the SampleServlet.java example in examples/servlet_example1 in
the 1.1-rc1 distro and replaced the handleRequest() with the following :

 public Template handleRequest( Context context )
    { 

        Vector v = new Vector();

        for (int i = 0; i < 10; i++)
        {
            Item item = new Item();

            item.setNumber( String.valueOf( i ) );

            v.addElement( item );
        }
            
        context.put("theList", v );
        
        Template outty = null;
        
        try
        {
            outty =  getTemplate("kelvin.vm");
        }
        catch( Exception e )
        {
            System.out.println("Error " + e);
        }
        return outty;
    }

where Item.java :

public class Item
{
    private String Thumbnail;
    private String Number;

    public Item()
    {
    }
    
    public String getThumbnail()
    {
        return Thumbnail;
    }
    public void setThumbnail(String s)
    {
        Thumbnail = s;
    }
    public String getNumber()
    {
        return Number;
    }
    public void setNumber(String s)
    {
        Number = s;
    }   
}

and the template kelvin.vm

<html><body>

Hello from Kelvin

#foreach($item in $theList)
  $item.number<br>
#end

#foreach($item in $theList)
  $item.getNumber()
#end

#foreach($item in $theList)
  $item.Number
#end

</body></html>

I then threw the Item.class and KelvinServlet.class into my
WEB-INF/class directory, threw kelvin.vm into the templates directory,
and gave it a whirl...

all worked fine.

geir


Kelvin Tan wrote:
> 
> Sorry about it. :)
> 
> I wasn't used to the time it took for my post to get out to the list. It had
> actually been 5 hours since I posted it, and I kinda needed it in a hurry.
> Guess was used to the lightning-fast response of jakarta-commons and
> turbine-users...oops
> 
> Anyhow here's the classes.
> 
> The Item class.
> public class Item
> {
>  public Item()
>  {
>  }
>  public String getThumbnail()
>  {
>   return Thumbnail;
>  }
>  public void setThumbnail(String s)
>  {
>   Thumbnail = s;
>  }
>  public String getNumber()
>  {
>   return Number;
>  }
>  public void setNumber(String s)
>  {
>   Number = s;
>  }
>  private String Thumbnail;
>  private String Number;
> }
> 
> In the VelocityServlet extender class
> 
> private static Vector ItemList = new Vector();
> protected Context createContext(HttpServletRequest req, HttpServletResponse
> res)
>   {
>   VelocityContext context = new VelocityContext();
> processFeed();
>   return context;
>  }
> 
> private void processFeed()
> {
> //There's some other logic here
> while (true)
> {
> Item csi = new Item();
> csi.setThumbnail(strbf.toString());
> csi.setNumber(strbf.toString());
>     if (csi.getThumbnail()!=null)
>     {
>     //Adds itself to the Collection of Items
>      ItemList.add(csi);
>     }
> }
> 
> public Template handleRequest( Context context )
>     {
>         context.put("ItemList", ItemList);
>         Template template = null;
>         try
>         {
>             template =  getTemplate("mytemplate.vm");
>         }
>         catch( ResourceNotFoundException rnfe )
>         {
>           // couldn't find the template
>         }
>         catch( ParseErrorException pee )
>         {
>           // syntax error : problem parsing the template
>         }
>         catch( Exception e )
>         {}
>         return template;
>     }
> 
>  protected void requestCleanup(HttpServletRequest req, HttpServletResponse
> res, Context context)
>  {
>   ItemList.clear();
>  }
> 
> And the template goes
> #foreach($csi in $ItemList)
> $csi.Thumbnail <br>
> $csi.Number <br>
> #end
> 
> and also have tried
> #foreach($csi in $ItemList)
> $csi.getThumbnail() <br>
> $csi.getNumber() <br>
> #end
> 
> The $csi.Thumbnail works now (not initially) but $csi.Number and
> $csi.getNumber() doesnt. Any clue?
> 
> Thanks in advance...and sorry again.
> 
> ----- Original Message -----
> From: "Geir Magnusson Jr." <ge...@optonline.net>
> To: <tu...@jakarta.apache.org>
> Sent: Friday, May 25, 2001 9:12 PM
> Subject: Re: [Off-Topic] Help with Velocity
> 
> > Kelvin Tan wrote:
> > >
> > > Hi, sorry to post on Turbine-users, but I kinda need help and
> Velocity-users
> > > isn't really forthcoming.
> >
> > Not to pile on (Kaspar already said this...) but you just posted
> > recently...
> >
> > I responded on velocity, although the message hasn't shown up yet -
> > maybe you'll get this one faster, but please take this back to vel-user
> > or vel-dev.
> >
> > The upshot is
> >
> > 1) make sure that gettter/setter methods are declared public.  Velocity
> > won't transgress access declarations.
> >
> > 2) send the skeleton of the class (no method body code) and we can take
> > a look.
> >
> > geir
> >
> > --
> > Geir Magnusson Jr.                           geirm@optonline.net
> > System and Software Consulting
> > Developing for the web?  See http://jakarta.apache.org/velocity/
> > "still climbing up to the shoulders..."
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: turbine-user-unsubscribe@jakarta.apache.org
> > For additional commands, e-mail: turbine-user-help@jakarta.apache.org
> >

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: [Off-Topic] Help with Velocity

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
Kelvin Tan wrote:
> 
> I see. What if I need to perform some processing from the servlet request in
> the servlet itself, not at the template level?
> 

That's the best place.  Just do it in the handleRequest() method.

geir

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: [Off-Topic] Help with Velocity

Posted by Kelvin Tan <ke...@relevanz.com>.
I see. What if I need to perform some processing from the servlet request in
the servlet itself, not at the template level?

----- Original Message -----
From: "Jon Stevens" <jo...@latchkey.com>
To: "velocity-user" <ve...@jakarta.apache.org>
Sent: Monday, May 28, 2001 9:52 AM
Subject: Re: [Off-Topic] Help with Velocity


> on 5/27/01 6:47 PM, "Kelvin Tan" <ke...@relevanz.com> wrote:
>
> > hmmm...wonder why I missed this because I scoured the User's Guide and
> > Developer's Guide for this and had to resort to overriding
createContext().
> > Is this documented? Does this apply for obtaining session data too??
> > session.getAttribute() and session.setAttribute()?
>
> It applies to any method. This is pretty standard stuff that follows the
> Java Bean specification pretty closely.
>
> -jon
>
>


Re: [Off-Topic] Help with Velocity

Posted by Jon Stevens <jo...@latchkey.com>.
on 5/27/01 6:47 PM, "Kelvin Tan" <ke...@relevanz.com> wrote:

> hmmm...wonder why I missed this because I scoured the User's Guide and
> Developer's Guide for this and had to resort to overriding createContext().
> Is this documented? Does this apply for obtaining session data too??
> session.getAttribute() and session.setAttribute()?

It applies to any method. This is pretty standard stuff that follows the
Java Bean specification pretty closely.

-jon


Re: [Off-Topic] Help with Velocity

Posted by Kelvin Tan <ke...@relevanz.com>.
> > I needed to actually read in something from the HttpServletRequest and
call
> > a request.getParameter(). Is there any other way to do this?
>
> sure - if you don't override createContext() which places it in the
> context for you :
>
> #set($param = $req.getParameter("foo"))
>
> will work.

hmmm...wonder why I missed this because I scoured the User's Guide and
Developer's Guide for this and had to resort to overriding createContext().
Is this documented? Does this apply for obtaining session data too??
session.getAttribute() and session.setAttribute()?

>
> > Of course, oddly enough, $csi.Thumbnail works but not $csi.Number. :)
>
> very strange.  It looks like it's being set - for debugging  purposes,
> can you call getNumber() right after you set it to make sure?
>
> What does the velocity log say?

It was a fault in the way I had implemented the loop. :) Will check through
more thoroughly in the future. Thanks for the help!

>
> geir
>
> --
> Geir Magnusson Jr.                           geirm@optonline.net
> System and Software Consulting
> Developing for the web?  See http://jakarta.apache.org/velocity/
> "still climbing up to the shoulders..."
>


Re: [Off-Topic] Help with Velocity

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
Kelvin Tan wrote:
> 
> [snip]
> 
> > Odd, I assume that the while(true) is really something else,  and you
> > are going to run into problems when you have more than one request
> > hitting this servlet at the same time because itemList is a class
> > member, but that shouldn't be causing the problem.
> >
> > Also, I personally would have not overridden createContext(), and put
> > something like
> >
> > itemList = processFeed();
> >
> > in my handleRequest() method, but that's not what we are here for.
> 
> I needed to actually read in something from the HttpServletRequest and call
> a request.getParameter(). Is there any other way to do this?

sure - if you don't override createContext() which places it in the
context for you :

#set($param = $req.getParameter("foo"))

will work.

> And actually you're right. Should've made itemList an instance member, or
> actually back to the item class where it belongs. Thanks. :)
> 
> [snip]
> > The things that immediately jump to mind is that the class Item that
> > gets included in the classpath isn't the one you think it is.
> >
> > I will give it a try to see what happens, but I can't see why theres a
> > problem.
> 
> Do I need to specifically place Item.class into the classpath? It's in my
> {tomcat_home}/webapps/{appname}/web-inf/classes directory, in the same place
> where the VelocityServlet extender is placed.

No - dropping into WEB-INF/classes is perfect.  Avoid the classpath at
all costs :)

 
> Of course, oddly enough, $csi.Thumbnail works but not $csi.Number. :)

very strange.  It looks like it's being set - for debugging  purposes,
can you call getNumber() right after you set it to make sure?

What does the velocity log say?

geir

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."

Re: [Off-Topic] Help with Velocity

Posted by Kelvin Tan <ke...@relevanz.com>.
[snip]

> Odd, I assume that the while(true) is really something else,  and you
> are going to run into problems when you have more than one request
> hitting this servlet at the same time because itemList is a class
> member, but that shouldn't be causing the problem.
>
> Also, I personally would have not overridden createContext(), and put
> something like
>
> itemList = processFeed();
>
> in my handleRequest() method, but that's not what we are here for.

I needed to actually read in something from the HttpServletRequest and call
a request.getParameter(). Is there any other way to do this?

And actually you're right. Should've made itemList an instance member, or
actually back to the item class where it belongs. Thanks. :)

[snip]
> The things that immediately jump to mind is that the class Item that
> gets included in the classpath isn't the one you think it is.
>
> I will give it a try to see what happens, but I can't see why theres a
> problem.

Do I need to specifically place Item.class into the classpath? It's in my
{tomcat_home}/webapps/{appname}/web-inf/classes directory, in the same place
where the VelocityServlet extender is placed.

Of course, oddly enough, $csi.Thumbnail works but not $csi.Number. :)

>
> geir
>
> --
> Geir Magnusson Jr.                           geirm@optonline.net
> System and Software Consulting
> Developing for the web?  See http://jakarta.apache.org/velocity/
> "still climbing up to the shoulders..."
>


Re: [Off-Topic] Help with Velocity

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
Kelvin Tan wrote:
> 
> Sorry about it. :)
> 
> I wasn't used to the time it took for my post to get out to the list. It had
> actually been 5 hours since I posted it, and I kinda needed it in a hurry.
> Guess was used to the lightning-fast response of jakarta-commons and
> turbine-users...oops

Gosh - you just want to make friends everywhere you go...

> 
> Anyhow here's the classes.
> 
> The Item class.
> public class Item
> {
>  public Item()
>  {
>  }
>  public String getThumbnail()
>  {
>   return Thumbnail;
>  }
>  public void setThumbnail(String s)
>  {
>   Thumbnail = s;
>  }
>  public String getNumber()
>  {
>   return Number;
>  }
>  public void setNumber(String s)
>  {
>   Number = s;
>  }
>  private String Thumbnail;
>  private String Number;
> }
> 

That looks fine.

> In the VelocityServlet extender class
> 
> private static Vector ItemList = new Vector();
> protected Context createContext(HttpServletRequest req, HttpServletResponse
> res)
>   {
>   VelocityContext context = new VelocityContext();
> processFeed();
>   return context;
>  }
> 
> private void processFeed()
> {
> //There's some other logic here
> while (true)
> {
> Item csi = new Item();
> csi.setThumbnail(strbf.toString());
> csi.setNumber(strbf.toString());
>     if (csi.getThumbnail()!=null)
>     {
>     //Adds itself to the Collection of Items
>      ItemList.add(csi);
>     }
> }
> 

Odd, I assume that the while(true) is really something else,  and you
are going to run into problems when you have more than one request
hitting this servlet at the same time because itemList is a class
member, but that shouldn't be causing the problem.

Also, I personally would have not overridden createContext(), and put
something like

itemList = processFeed();

in my handleRequest() method, but that's not what we are here for.

Anyhow...

> public Template handleRequest( Context context )
>     {
>         context.put("ItemList", ItemList);
>         Template template = null;
>         try
>         {
>             template =  getTemplate("mytemplate.vm");
>         }
>         catch( ResourceNotFoundException rnfe )
>         {
>           // couldn't find the template
>         }
>         catch( ParseErrorException pee )
>         {
>           // syntax error : problem parsing the template
>         }
>         catch( Exception e )
>         {}
>         return template;
>     }
> 
>  protected void requestCleanup(HttpServletRequest req, HttpServletResponse
> res, Context context)
>  {
>   ItemList.clear();
>  }
> 
> And the template goes
> #foreach($csi in $ItemList)
> $csi.Thumbnail <br>
> $csi.Number <br>
> #end
> 
> and also have tried
> #foreach($csi in $ItemList)
> $csi.getThumbnail() <br>
> $csi.getNumber() <br>
> #end
> 
> The $csi.Thumbnail works now (not initially) but $csi.Number and
> $csi.getNumber() doesnt. Any clue?
> 
> Thanks in advance...and sorry again.

The things that immediately jump to mind is that the class Item that
gets included in the classpath isn't the one you think it is.

I will give it a try to see what happens, but I can't see why theres a
problem.

geir

-- 
Geir Magnusson Jr.                           geirm@optonline.net
System and Software Consulting
Developing for the web?  See http://jakarta.apache.org/velocity/
"still climbing up to the shoulders..."