You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by Jason Pettiss <ja...@CatalisHealth.com> on 2005/05/24 22:52:14 UTC

Template output for array variables

Maybe I'm crazy, but here is an idea.  When using a template variable 
which happens to be an array or list as a scalar, instead of using 
toString() as the value, use the first item's toString().  If I have a 
string array of size one under key 'name', ${name} will be replaced 
with, say, "[Ljava.lang.String;@4dd1b".  Which is useful only insofar as 
it tells me, the template author, that I need to use #foreach.

I suggest this because it would be useful to create a per-request 
VelocityContext object that takes as its first constructor argument the 
result of 'new HashMap(request.getParameterMap())'.  This effectively 
allows me to treat request parameters the same as request scoped 
objects, which greatly reduces the mundaneity of writing a typical 
webapp.  The most annoying common thing I find myself doing is 
ctx.put(paramName, request.getParameter(paramName)), just so the values 
that are posted are available not only to my request handler, but also 
to the resulting template page.  This is incredibly useful for 
maintaining relatively stateless pages.

Anyway, the javadoc for ServletRequest.getParameterMap() says this:*
*
--
Returns an immutable java.util.Map containing parameter names as keys 
and parameter values as map values. The keys in the parameter map are of 
type String. The values in the parameter map are of type String array.
--

Thus back to my original suggestion.  Right now of course, I get 
[Ljava.lang.String;@xxxxxx for all my request parameters that I try to 
access on my template, unless I wrap them with an impotent foreach: 
#foreach($myvar)$myvar#end.

Am I goofy?  Would it break anything to treat lists as scalars when they 
are in scalar context in a template?  I can't imagine anyone uses the 
current output of such a variable, other than for debugging purposes.

Jason Pettiss
jason.pettiss@CatalisHealth.com



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


Re: Template output for array variables

Posted by Jason Pettiss <ja...@CatalisHealth.com>.
Update... I am constructing my VelocityContext by handing it new 
HashMap(request.getParameterMap()) so as to allow request parameters to 
be treated like request scoped variables and allow them to seamlessly 
'flow through' a request.  I was having a problem as $paramName was 
outputting an array toString rather than the actual parameter.  So I 
constructed a ReferenceInsertionEventHandler, which fixed that problem.

Turns out this is just a bit daft, because now a simple #if against a 
literal parameter will fail.  If I hit "?apples=yummy" and on my 
template I have:

#if( $apples == 'yummy' )
Apples are yummy.
#else
I am daft.
#end

I will always be reminded that sometimes poking at a hornets' nest 
stings you.  In this case I assume that since $apples is a String[] 
instead of a String, that the #if is failing because it doesn't use 
ReferenceInsertionEventHandler to obtain the value of a variable in 
order to test against-- only to output.

Back to the drawing board.  Was hoping to make this 'efficient' by 
simply wrapping the raw parameter map, but it's looking like it'll be 
safer just to give up this angle of attack.  :-)

Jason Pettiss
jason.pettiss@CatalisHealth.com


Jason Pettiss wrote:

> Amazing.  Awesome.  Exactly what I need.
>
> class ReferenceInserter
>    implements ReferenceInsertionEventHandler
> {
>    public Object referenceInsert(
>        String reference,
>        Object value)
>    {
>        if (value instanceof Object[])
>        {
>            Object[] a = (Object[])value;
>            if (a.length>0) value = a[0];
>        }
>        return value;
>    }   }
>
> I love velocity.  :-)
>
> Thanks,
>
> Jason Pettiss
> jason.pettiss@CatalisHealth.com
>


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


Re: Template output for array variables

Posted by Jason Pettiss <ja...@CatalisHealth.com>.
Amazing.  Awesome.  Exactly what I need.

class ReferenceInserter
    implements ReferenceInsertionEventHandler
{
    public Object referenceInsert(
        String reference,
        Object value)
    {
        if (value instanceof Object[])
        {
            Object[] a = (Object[])value;
            if (a.length>0) value = a[0];
        }
        return value;
    }   
}

I love velocity.  :-)

Thanks,

Jason Pettiss
jason.pettiss@CatalisHealth.com



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


Re: Template output for array variables

Posted by Shinobu Kawai <sh...@gmail.com>.
Hi Jason,

> Maybe I'm crazy, but here is an idea.  When using a template variable
> which happens to be an array or list as a scalar, instead of using
> toString() as the value, use the first item's toString().  If I have a
> string array of size one under key 'name', ${name} will be replaced
> with, say, "[Ljava.lang.String;@4dd1b".  Which is useful only insofar as
> it tells me, the template author, that I need to use #foreach.

When there's a will, there's a way.  You can create a custom
ReferenceInsertionEventHandler to get the desired behaviour.
  http://jakarta.apache.org/velocity/developer-guide.html#EventCartridge%20and%20Event%20Handlers

Best regards,
-- Shinobu

--
Shinobu Kawai <sh...@gmail.com>

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