[prev in list] [next in list] [prev in thread] [next in thread] 

List:       velocity-user
Subject:    Re: Late Binding of variables
From:       "Geir Magnusson Jr." <geirm () optonline ! net>
Date:       2001-10-19 11:49:06
[Download RAW message or body]

On 10/19/01 1:14 AM, "Byron Foster" <bfoster@base2.cc> wrote:

> Hello,
> 
> I was wondering if velocity has the ability to do late binding in
> variables.. example:
> 
> #set ($A = "foo")
> #set ($B = $A)
> #set ($A = "bar")
> 
> ## I would like an approach so that the following would print "bar"
> $B

Reading ahead, there are several issues mixed up in this.

(This reminds me of something else to document...)

Velocity uses references, just like Java.  Therefore, you can do things like

Suppse you have a class

Public class Foo
{
  String foo = "default value";

  public void setString( String f )
  {
     f= foo;
  }

  public String toString()
  {
    foo;
  }|

Then you can

## set $a to be an object from the context

#set($a = $fooobject)

## now, make $b reference the same object

#set($b = $a )

## modify $a

$a.setString( "Hello from Foo" )

## and when you show $b, you should get 'Hello from Foo' rather than
'default value'

$b.toString()

> 
> The reason I am looking for this functionality is so that I can build a
> generalized report template as follows:
> 
> report.vm:
> -------------------------------------------------------
> <table>
> #foreach($row in $data)
>   <tr>
>     #foreach($heading in $headings)
>       <th>$heading</th>
>     #end
>   </tr>
>   <tr>
>     #foreach($col in $props)
>     <td>$col</td>
>     #end
>   </tr>
> #end
> </table>
> -------------------------------------------------------
> foo.vm
> ------------------------------------------------------
> -- Some html here --
> 
> #set ($data = "$users")
> #set ($row = "$user")
> #set ($headings = ["Username", "Firstname", "LastName"])
> #set ($props = ['<a href=showuser?id=$user.id>$user.username</a>',
> '$user.firstname', '$user.lastname'])
> #parse (report.vm)
> 
> --- Some more html here --
> -------------------------------------------------------
> 
> So of corse the above won't compile, but it show what I would like to
> do.  So what really needs to happen here is that $row would expand to
> $user in the foreach directive in report.vm.  More importantly as $col
> interates through $props in report.vm $col would be evaluated with more
> than one pass:  $col->$user.firstname->"John"

I think what you are looking for is like an iterative 'eval' of references.

No, we don't (and won't) do that. ("This ain't Perl...")

However, you could easily write an eval() tool using some of the helper
methods in the o.a.v.app.Velocity class. (Or VelocityEngine...)

Maybe I'll write one and throw it somewhere.

That might be the best way for you.

> 
> Now I'm working on a velocimacro approach which looks something like this:
> 
> #macro (reporthead $headings)
> <table><tr>
>   #foreach ($col in $headings)
>     <th>$col</th>
>   #end
>  </tr>
> #end
> 
> #macro (reportcol $col)
>  <td>$col</td>   
> #end
> 
> ## for two column report
> #macro (report2 $headings $data $row $col1 $col2)
>  #reporthead($headings)
>  #foreach ($row in $data)
>    <tr>
>    #reportcol($col1)
>    #reportcol($col2)
>    </tr>
>  #end
> </table>
> #end
> 
> #for 3 column report
> #macro (report2 $headings $data $row $col1 $col2 $col3)
>  #reporthead($headings)
>  #foreach ($row in $data)
>    <tr>
>    #reportcol($col1)
>    #reportcol($col2)
>    #reportcol($col3)
>    </tr>
>  #end
> </table>
> #end
> 
> 
> so I can call a report with three columns like so:
> #set ($headings = ["Username", "First Name", "Last Name"])
> #report3($headings $data $users $user "<a
> href=getuser?id=$user.id>$user.username<a>" "user.first" "user.last"
> 
> This works ok, but  the macros are a little redundant and it gets
> teadious when there is allot of formating html since it needs to be
> coppied to report1 report2 report3 ...
> 
> Hmm, didn't think this was going to be so long.
> 
> Any Suggestions, insight?
> 
> Thanks much!
> Byron
> 

Yep, that's going to get tedious.  You are doing the right thing, taking
advantage of the 'evaluation inside' property of VMs when you pass ""
strings, but I still think that you might just want a little eval tool that
takes a string and renders that against the context.

geir

-- 
Geir Magnusson Jr.     geirm@optonline.net
System and Software Consulting
"They that can give up essential liberty to obtain a little temporary safety
deserve neither liberty nor safety." - Benjamin Franklin

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic