You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Mike Kienenberger <mk...@alaska.net> on 2004/01/16 21:45:52 UTC

toolbox.xml and email templates

I'm using Velocity with Struts 1.1 to generate web pages.

I'm also using it to generate email messages as well.
To do so, I've been using:

		Context context = new VelocityContext();
			Velocity.mergeTemplate(aTemplateName, "ISO8859-1", aContext, writer);

This generates email messages like:
============
You have successfully paid ${number.format('currency', $amountValue)} on 
${date.format("h:mm a MMMMM d, yyyy (zzz)", $dateValue)} for account #9 (at 
Tesoro Alaska)
============

So my guess is that my $number and $date tools aren't available in the 
context.

My questions are:

1) Is this a reasonable assumption of the problem considering I'm using new 
VelocityContext()?

2) How can I get my tools.xml tools into my email contexts programmatically? 
 [A documentation pointer is sufficient, but detailed responses would also 
be properly appreciated.]


Thanks!

-Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Mike Kienenberger <mk...@alaska.net>.
Nathan Bubna <na...@esha.com> wrote:
> so, to get a full chained context (like the VelocityViewServlet uses) in 
your
> Struts Action, do something like this:
> 
> specify the location of your toolbox.xml as a context param in your 
web.xml
> (instead of an init-param in your servlet's config):
> 
> <context-param>
>    <param-name>org.apache.velocity.toolbox</param-name>
>    <param-value>/WEB-INF/toolbox.xml</param-value>
> </context-param>
> 
> to a context to use, do something like this in your action code:
> 
> // this is how you get the ServletContext in an Action
> ServletContext servletCtx = getServlet().getServletContext();
> 
> // this will retrieve the context parameter
> String file = servletCtx.getInitParameter("org.apache.velocity.toolbox");
> 
> // this should get the *very same* ToolboxManager instance
> // that your VelocityViewServlet is using
> ToolboxManager toolMgr = ServletToolboxManager.getInstance(servletCtx, 
file);
> 
> // this creates a context with access to tools, req/res/sess/ctx, and 
their
> attributes
> ChainedContext context = new ChainedContext(null, request, response,
> servletCtx);
> context.setToolbox(toolMgr.getToolboxContext(ctx));


I want to keep my Email business logic separate from the web server logic.

So I've created a method in my Application (extends ActionServlet) object.  
(I already retrieve my MessageResources the same way).

	public ToolboxContext getToolboxContext()
	{
		ServletContext servletCtx = getServletContext();
		
		//	this will retrieve the context parameter
		 String file = servletCtx.getInitParameter("org.apache.velocity.toolbox");
		
		//	this should get the *very same* ToolboxManager instance
		//	that your VelocityViewServlet is using
		ToolboxManager aToolboxManager =  
ServletToolboxManager.getInstance(servletCtx, file);			 
		return aToolboxManager.getToolboxContext(ctx);
	}

I'm not certain what value should be set for "ctx" in 
getToolboxContext(ctx).
Is this servletCtx?

Once I have this method, I plan to use

	Context context = new VelocityContext();
	context.setToolbox(theApplicationObject.getToolboxContext());
	Velocity.mergeTemplate(aTemplateName, "ISO8859-1", aContext, writer);

which seems like it'd be sufficient for importing my toolbox tools.
Or am I overlooking something?


Also, what are the pros and cons of using the servlet's ToolboxContext 
compared with generating a ToolBoxContext directly?
 

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Nathan Bubna <na...@esha.com>.
Nathan Bubna said:
> Mike Kienenberger said:
> > I'm using Velocity with Struts 1.1 to generate web pages.
> >
> > I'm also using it to generate email messages as well.
...
> > 2) How can I get my tools.xml tools into my email contexts
programmatically?
> >  [A documentation pointer is sufficient, but detailed responses would also
> > be properly appreciated.]
>
> the best way to do that probably depends on your setup.  if you want to use
a
> toolbox totally independent of servlets, your best bet is to use the
> XMLToolboxManager directly.  for that you'd do something like:
>
> ToolboxManager mgr = new XMLToolboxManager();
> mgr.load(inputStreamFromToolboxFile);
> VelocityContext context = mgr.getToolboxContext(null);
>
> and then use the context as you wish.  this is probably the simplest way to
do
> this, if not the most ideal.  since it sounds like you're doing this as part
> of a Struts webapp, i'm guessing the emails are being generated during the
> execution of a custom Action.  if so, let me know, i'll see if i can't hack
up
> an example of a better way (using the same ServletToolboxManager that the
> VelocityViewServlet is using).

ok, i went ahead and figured it out anyway.  it'll be good to have this in the
list archives if nothing else.

so, to get a full chained context (like the VelocityViewServlet uses) in your
Struts Action, do something like this:

specify the location of your toolbox.xml as a context param in your web.xml
(instead of an init-param in your servlet's config):

<context-param>
   <param-name>org.apache.velocity.toolbox</param-name>
   <param-value>/WEB-INF/toolbox.xml</param-value>
</context-param>

to a context to use, do something like this in your action code:

// this is how you get the ServletContext in an Action
ServletContext servletCtx = getServlet().getServletContext();

// this will retrieve the context parameter
String file = servletCtx.getInitParameter("org.apache.velocity.toolbox");

// this should get the *very same* ToolboxManager instance
// that your VelocityViewServlet is using
ToolboxManager toolMgr = ServletToolboxManager.getInstance(servletCtx, file);

// this creates a context with access to tools, req/res/sess/ctx, and their
attributes
ChainedContext context = new ChainedContext(null, request, response,
servletCtx);
context.setToolbox(toolMgr.getToolboxContext(ctx));


i haven't tested this code, but it should give you the basic idea.  this is
basically a shortened version of what happens in the VVS's initToolbox() and
createContext() methods.

Nathan Bubna
nathan@esha.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Mike Kienenberger <mk...@alaska.net>.
Nathan Bubna <na...@esha.com> wrote:
> yeah, the VelocityView tools are very dependent on the Servlet API with 
the
> exception of the ViewRenderTool and (with just a little work) the
> AbstractSearchTool.
> 
> any LinkTool designed for use w/o access to the request and response would 
be
> a very different creature.  useful perhaps, but quite different. :)

Right.  It was very obvious in retrospect that formTool, linkTool, msgTool, 
etc, all had to be removed along with a couple of custom tools.

But after that, my email Velocity templates seem to be working just fine.

Thanks again!

-Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Nathan Bubna <na...@esha.com>.
Mike Kienenberger said:
> Another gotcha for anyone else attempting to import toolbox.xml into a
> non-Servlet Velocity context:
> ================================
> java.lang.IllegalArgumentException: Tool can only be initialized with a
> ViewContext
> at org.apache.velocity.tools.view.tools.LinkTool.init(LinkTool.java:291)
> at
>
org.apache.velocity.tools.view.ViewToolInfo.getInstance(ViewToolInfo.java:171)
> at
>
org.apache.velocity.tools.view.XMLToolboxManager.getToolboxContext(XMLToolboxM
anager.java:150)
> ================================
> I had to create an "email.toolbox.xml" file that contained no tools that
> referenced servlet resources.
> Ie, no tools other than those in org.apache.velocity.tools.generic or tools
> based on generic tools.

yeah, the VelocityView tools are very dependent on the Servlet API with the
exception of the ViewRenderTool and (with just a little work) the
AbstractSearchTool.

any LinkTool designed for use w/o access to the request and response would be
a very different creature.  useful perhaps, but quite different. :)

Nathan Bubna
nathan@esha.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Mike Kienenberger <mk...@alaska.net>.
Another gotcha for anyone else attempting to import toolbox.xml into a 
non-Servlet Velocity context:

================================

java.lang.IllegalArgumentException: Tool can only be initialized with a 
ViewContext
	at org.apache.velocity.tools.view.tools.LinkTool.init(LinkTool.java:291)
	at 
org.apache.velocity.tools.view.ViewToolInfo.getInstance(ViewToolInfo.java:171)
	at 
org.apache.velocity.tools.view.XMLToolboxManager.getToolboxContext(XMLToolboxManager.java:150)
	at 
com.gvea.struts.ebpp.framework.Application.getToolboxContext(Application.java:124)

================================

I had to create an "email.toolbox.xml" file that contained no tools that 
referenced servlet resources.
Ie, no tools other than those in org.apache.velocity.tools.generic or tools 
based on generic tools.

-Mike



---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Nathan Bubna <na...@esha.com>.
Mike Kienenberger said:
> Nathan Bubna <na...@esha.com> wrote:
> > Mike Kienenberger said:
> > > 2) How can I get my tools.xml tools into my email contexts
> programmatically?
> >
> > if you want to use a
> > toolbox totally independent of servlets, your best bet is to use the
> > XMLToolboxManager directly.  for that you'd do something like:
> >
> > ToolboxManager mgr = new XMLToolboxManager();
> > mgr.load(inputStreamFromToolboxFile);
> > VelocityContext context = mgr.getToolboxContext(null);
>
> To answer my own question, I see from the source that getToolboxContext(ctx)
> from the ServletToolboxManager approach requires ctx be a ChainedContext
> which requires a request/response which I don't want to provide in my email
> system.

d'oh!  and i was halfway through telling you this in another email. :)

> So I'm looking at the XMLToolboxManager approach.
>
> However, XMLToolboxManager is abstract.  The only subclass I found for it
> was ServletToolboxManager, which pretty much goes back to a Servlet-based
> solution or creating my own subclass.   I don't understand why
> XMLToolboxManager needs to be abstract which probably means I'd run into
> problems making a subclass.

well, the XMLToolboxManager is no longer abstract in 1.1-dev and won't be in
the next release.  so you can build VelocityTools from CVS or create a
subclass like:

public class MyToolboxManager extends XMLToolboxManager {}

somehow i doubt you'll run into problems with that. :)

oh, and one thing i should note about the XMLToolboxManager way i showed you
before.  the ToolboxContext is immutable, so #set() and #foreach() and stuff
may not work if you use it directly as my initial, untested example showed
you.  better to do:

ToolboxManager mgr = new XMLToolboxManager();
mgr.load(inputStreamFromToolboxFile);
ToolboxContext toolCtx = mgr.getToolboxContext(null);
VelocityContext context = new VelocityContext(toolCtx);

and if you want to find code to mimic for getting the input stream to load
XMLToolboxManager, i suggest looking into the source of
ServletToolboxManager.getInstance() and VelocityViewServlet.initToolbox()

Nathan Bubna
nathan@esha.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Mike Kienenberger <mk...@alaska.net>.
Nathan Bubna <na...@esha.com> wrote:
> Mike Kienenberger said:
> > 2) How can I get my tools.xml tools into my email contexts 
programmatically?
> 
> if you want to use a
> toolbox totally independent of servlets, your best bet is to use the
> XMLToolboxManager directly.  for that you'd do something like:
> 
> ToolboxManager mgr = new XMLToolboxManager();
> mgr.load(inputStreamFromToolboxFile);
> VelocityContext context = mgr.getToolboxContext(null);

To answer my own question, I see from the source that getToolboxContext(ctx) 
from the ServletToolboxManager approach requires ctx be a ChainedContext 
which requires a request/response which I don't want to provide in my email 
system.

So I'm looking at the XMLToolboxManager approach.

However, XMLToolboxManager is abstract.  The only subclass I found for it 
was ServletToolboxManager, which pretty much goes back to a Servlet-based 
solution or creating my own subclass.   I don't understand why 
XMLToolboxManager needs to be abstract which probably means I'd run into 
problems making a subclass.

-Mike

---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org


Re: toolbox.xml and email templates

Posted by Nathan Bubna <na...@esha.com>.
Mike Kienenberger said:
> I'm using Velocity with Struts 1.1 to generate web pages.
>
> I'm also using it to generate email messages as well.
> To do so, I've been using:
>
> Context context = new VelocityContext();
> Velocity.mergeTemplate(aTemplateName, "ISO8859-1", aContext, writer);
...
> So my guess is that my $number and $date tools aren't available in the
> context.
...
> 1) Is this a reasonable assumption of the problem considering I'm using new
> VelocityContext()?

yep, that's the problem.

> 2) How can I get my tools.xml tools into my email contexts programmatically?
>  [A documentation pointer is sufficient, but detailed responses would also
> be properly appreciated.]

the best way to do that probably depends on your setup.  if you want to use a
toolbox totally independent of servlets, your best bet is to use the
XMLToolboxManager directly.  for that you'd do something like:

ToolboxManager mgr = new XMLToolboxManager();
mgr.load(inputStreamFromToolboxFile);
VelocityContext context = mgr.getToolboxContext(null);

and then use the context as you wish.  this is probably the simplest way to do
this, if not the most ideal.  since it sounds like you're doing this as part
of a Struts webapp, i'm guessing the emails are being generated during the
execution of a custom Action.  if so, let me know, i'll see if i can't hack up
an example of a better way (using the same ServletToolboxManager that the
VelocityViewServlet is using).

Nathan Bubna
nathan@esha.com


---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-user-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-user-help@jakarta.apache.org