You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@velocity.apache.org by Darin Kelkhoff <da...@sportingnews.com> on 2001/10/19 20:28:23 UTC

passing parameters to #parse'ed files0

hello, list,

i'm getting ready to work on a project, porting my company's templating 
development from a proprietary vendor product to velocity.  I'll be 
responsible for determining exactly how velocity will be used by the other 
programmers and designers here, and i'm trying to make this transition as 
easy as possible for all the other team members (lower the learning curve:  
i'm not worried about the velocity syntax being tough to learn, just that if 
we have to change our way of thinking about templates too much, that would be 
harder to learn.)

one fairly major component of our old system that i'm not sure how to convert 
into velocity is the user-defined tags that take formal parameters in our old 
system.  it seems obvious that in all our old templates when we made calls to 
user-defined tags, that those could just be replaced now with calls to 
#parse() other template files (for some encapsulation of common code, etc).  
the problem is that our old system let us pass parameters into these tags, 
and i don't think that i can do that using #parse().

Old system:
------------
<table>0
   <? ITERATION CONSTRUCT ?>
      <? foo-tag param1=$bar1 param2=$bar2 ?>
   <? END ITERATION ?>
</table>


What we'd like w/ velocity:
---------------------------
<table>
   #foreach($i in $iterate)
      ## foo.vm takes 2 parameters (named param1 & param2)
      #parse("foo.vm" $bar1 $bar2)
   #end
</table>

i can see a few potential solutions, but none of them are quite as slick as 
I'd like to make things.  first of all, i could make a rule that if a 
#parse'd file needed parameters, that it would have to just define a macro, 
which would then be called with the parameters after it was #parse'd, similar 
to this:

Solution 1:
-----------
## foo.vm defines #foo-macro
#parse("foo.vm")  
<table>
   #foreach($i in $iterate)
      ## foo-macro takes 2 parameters (named param1 & param2)
      #foo-macro($bar1 $bar2)
   #end
</table>

two reasons i don't like this approach are that 1.) it changes what we are 
currently doing, by having to #parse and then #foo-macro, and 2.) it causes 
us to have 2 different ways of using #parse (the normal approach, just to 
include the html (and vtl) in a file, and 2 to include a macro in the file, 
only for that macro to be called later). 

the second possible solution i see would be for each file that gets #parse'd, 
that if it needed parameters, they would have to be #set before the file got 
#parse'd.  similar to this:

Solution 2:
-----------
<table>
   #foreach($i in $iterate)
      #set($param1 = $bar1)
      #set($param2 = $bar2)
      ## foo.vm depends on $param1 and $param2 to be set
      #parse("foo.vm")
   #end
</table>

the problem here is that it requires everyone who uses foo.vm to have to know 
exactly what parameters it expects.   Also, the designers would have to know 
to set these params in the context, can have to no not to overwrite current 
values, there are all kindsa problems with this solution.

a third solution has been mentioned is that we could fake passing parameters 
with #parse ourselves, as we are planning on having all our templates run 
through some sort of "preprocessor" anyway when they are moved from 
development into testing (for now, just responsible for some syntax checking 
and file moving).  i'm not sure if this sounds like a decent idea, or how 
workable this would be, but i guess it is another option.

has anyone else ever thought about doing this?  how are similar issues 
handled in other places?  should i just make some files be #parsed, and 
others be #parse'd and then #macro-call'd ?  

thanks for any help, and sorry for my verbosity.
--darin


-- 
Darin Kelkhoff
darink@sportingnews.com

Re: passing parameters to #parse'ed files0

Posted by Bill Burton <bi...@progress.com>.
Hello,

There are a couple of variants to your ideas I can think of that would
allow you to use named parameters and provide a consistent way for all
your tag calls.

<table>
   #foreach($i in $iterate)
      ## Generic way to specify named parameters
      #set($params = [ "param1=$bar1", "param2=$bar2" ])
      ## The #parsetag macro calls a helper tool in the context to parse
parameter
      ## names out of the $params ArrayList putting them into the
Context.  It then
      ## calls #parse.
      #parsetag("foo.vm" $params)
   #end
</table>

<table>
   #foreach($i in $iterate)
      ## doTag method parses out arguments putting param1 and param2 into
the 
      ## context and then merges the foo.vm template.  
      $tags.doTag("foo.vm", "param1=$bar1", "param2=$bar2")
   #end
</table>

In the above example, you could create overloaded doTag methods that
handle from zero to N arguments after the .vm file argument.  This assumes
that the number of potential arguments does not get too large.  The doTag
methods would parse all arguments after the .vm file putting the named
parameter into the context, and then merge the template.  

A variant to this is to have a separate method call mapped to each tag. 
This could imply the name of the .vm file if you want.

It would be nice if Velocity provided a little context tool to make it
easy to handle named parameters.  This kind if thing is rather common when
converting from JSP or other tag-based environment where parameters are
specified with attribute names.  Resorting to positional parameters is not
always acceptable.

Hope this helps,
-Bill

Darin Kelkhoff wrote:
> 
> hello, list,
> 
> i'm getting ready to work on a project, porting my company's templating
> development from a proprietary vendor product to velocity.  I'll be
> responsible for determining exactly how velocity will be used by the other
> programmers and designers here, and i'm trying to make this transition as
> easy as possible for all the other team members (lower the learning curve:
> i'm not worried about the velocity syntax being tough to learn, just that if
> we have to change our way of thinking about templates too much, that would be
> harder to learn.)
> 
> one fairly major component of our old system that i'm not sure how to convert
> into velocity is the user-defined tags that take formal parameters in our old
> system.  it seems obvious that in all our old templates when we made calls to
> user-defined tags, that those could just be replaced now with calls to
> #parse() other template files (for some encapsulation of common code, etc).
> the problem is that our old system let us pass parameters into these tags,
> and i don't think that i can do that using #parse().
> 
> Old system:
> ------------
> <table>0
>    <? ITERATION CONSTRUCT ?>
>       <? foo-tag param1=$bar1 param2=$bar2 ?>
>    <? END ITERATION ?>
> </table>
> 
> What we'd like w/ velocity:
> ---------------------------
> <table>
>    #foreach($i in $iterate)
>       ## foo.vm takes 2 parameters (named param1 & param2)
>       #parse("foo.vm" $bar1 $bar2)
>    #end
> </table>
> 
> i can see a few potential solutions, but none of them are quite as slick as
> I'd like to make things.  first of all, i could make a rule that if a
> #parse'd file needed parameters, that it would have to just define a macro,
> which would then be called with the parameters after it was #parse'd, similar
> to this:
> 
> Solution 1:
> -----------
> ## foo.vm defines #foo-macro
> #parse("foo.vm")
> <table>
>    #foreach($i in $iterate)
>       ## foo-macro takes 2 parameters (named param1 & param2)
>       #foo-macro($bar1 $bar2)
>    #end
> </table>
> 
> two reasons i don't like this approach are that 1.) it changes what we are
> currently doing, by having to #parse and then #foo-macro, and 2.) it causes
> us to have 2 different ways of using #parse (the normal approach, just to
> include the html (and vtl) in a file, and 2 to include a macro in the file,
> only for that macro to be called later).
> 
> the second possible solution i see would be for each file that gets #parse'd,
> that if it needed parameters, they would have to be #set before the file got
> #parse'd.  similar to this:
> 
> Solution 2:
> -----------
> <table>
>    #foreach($i in $iterate)
>       #set($param1 = $bar1)
>       #set($param2 = $bar2)
>       ## foo.vm depends on $param1 and $param2 to be set
>       #parse("foo.vm")
>    #end
> </table>
> 
> the problem here is that it requires everyone who uses foo.vm to have to know
> exactly what parameters it expects.   Also, the designers would have to know
> to set these params in the context, can have to no not to overwrite current
> values, there are all kindsa problems with this solution.
> 
> a third solution has been mentioned is that we could fake passing parameters
> with #parse ourselves, as we are planning on having all our templates run
> through some sort of "preprocessor" anyway when they are moved from
> development into testing (for now, just responsible for some syntax checking
> and file moving).  i'm not sure if this sounds like a decent idea, or how
> workable this would be, but i guess it is another option.
> 
> has anyone else ever thought about doing this?  how are similar issues
> handled in other places?  should i just make some files be #parsed, and
> others be #parse'd and then #macro-call'd ?
> 
> thanks for any help, and sorry for my verbosity.
> --darin
> 
> --
> Darin Kelkhoff
> darink@sportingnews.com

Re: passing parameters to #parse'ed files0

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 10/24/01 9:13 AM, "Darin Kelkhoff" <da...@sportingnews.com> wrote:

> [snip]
>>>> Why is the VM solution below different that that of your parameterized
>>>> tags?
>>>> 
>>>> <table>
>>>>   #foreach( $item in $itemset )
>>>>      #foo( $item.foo $item.bar )
>>>>   #end
>>>> </table>
>>>> 
>>>> (or whatever you do to get params)
>>>> 
>>>> This seems a direct parallel to your tag approach.
>>>> 
>>>> What are the drawbacks of this for you?
>>> 
>>> so, if we would have all our old "tag"'s now exist as macros in a macro
>>> library file.  good, then we would still have a consistent calling method
>>> (whether or not params were needed).  i guess the only trick now is the
>>> management of the vm library file(s).  we can have as many as we want,
>>> correct?
>> 
>> Yes.  They don't even have to be in a file, technically.  Could come from
>> anywhere, like a jar, database or gerbil, assuming you write a
>> GerbilResourceLoader ...
> [snip]
> 
> okay, so right now i'm pretty well down to considering 2 solutions.  the
> first would be just defining all our old tags to be macros and placing them
> in vm libraries. 
> 
> the second would be a macro that simulates the behaviour i was looking for in
> #parse (thanks, bill burton):
> 
> <table>
>  #foreach($i in $iterate)
>     ## Generic way to specify named parameters
>     #set($params = [ "param1=$bar1", "param2=$bar2" ])
>     ## The #parsetag macro calls a helper tool in the context
>     ## to parse parameter names out of the $params ArrayList
>     ## putting them into the Context.  It then calls #parse.
>     #parsetag("foo.vm" $params)
>  #end
> </table>
> 
> so the question i pose to the list now is, which of these methods would bear
> the least expense at run time?
> 
> bearing in mind that we have around 400 tags in production at all times,
> (that is, 4 sites each with ~40 for layout, and about 100 distinct templates
> each with 2 or 3 for data) with edits being made and new tags installed
> daily, our macro library files would be fairly large and updated quite often.

Would you push the macro libs out to production ad-hoc?  How many times a
day?
 
> does performance using macro libs degrade when they reach sizes like this?

The honest truth is "I don't know", but I'm not frightened :

- management performance should scale like a map, which is used to hold and
look these things up.

- when a template is used for the first time, it is parsed, initialized and
cached, and any VMs is also parsed, initialized and cached, so even if the
management of the VM lib didn't scale well (and I think it will...), once a
template is parsed and cached, it doesn't go back to the VM management
system again.

> how does the caching work with a macro in a library?

For the most part, all macros are treated the same.  If they come from a
library, there is a switch that lets them be reloaded when the template that
they come from is changed.

For this to work, the templates that *use* the macro also can't be cached,
as once they are cached, they don't ever go back to the VM system.

> if a template 
> containing one of these macros is cached, is the library rechecked every time
> the template is used?

No.

> 
> the second solution seems to be more costly every time it's used, as (i
> assume) it redefines the macro used by foo.vm every time foo.vm is parsed.

Yes, could very well be.  There might be some optimization tricks, but not
sure.
 
> if runtime efficiency were even, i'd like to go with sol. 1 (the libraries),
> as it is the most intuitive for developers compared to what we currently
> have.  if anyone can give me reason why its a bad solution though, i'd
> appreciate hearing it now.

I think libraries are the way to go.  The fact that it is 'conventional'
means that improvements to the VM system will benefit you, and your app may
also influence "large-scale features and practice".

In the end, I think what will matter is how often changes are deployed to
production, and what you expect to happen when changes are deployed.
Restarting the webapp would be the best thing, but you might not be able to
afford that.  Adding autoload and some kind of cache dump might be the way
to go.
 
> thanks much,
> --darin

-- 
Geir Magnusson Jr.                       geirm@optonline.net
System and Software Consulting
You're going to end up getting pissed at your software
anyway, so you might as well not pay for it. Try Open Source.



Re: passing parameters to #parse'ed files0

Posted by Darin Kelkhoff <da...@sportingnews.com>.
[snip]
> >> Why is the VM solution below different that that of your parameterized
> >> tags?
> >>
> >> <table>
> >>   #foreach( $item in $itemset )
> >>      #foo( $item.foo $item.bar )
> >>   #end
> >> </table>
> >>
> >> (or whatever you do to get params)
> >>
> >> This seems a direct parallel to your tag approach.
> >>
> >> What are the drawbacks of this for you?
> >
> > so, if we would have all our old "tag"'s now exist as macros in a macro
> > library file.  good, then we would still have a consistent calling method
> > (whether or not params were needed).  i guess the only trick now is the
> > management of the vm library file(s).  we can have as many as we want,
> > correct?
>
> Yes.  They don't even have to be in a file, technically.  Could come from
> anywhere, like a jar, database or gerbil, assuming you write a
> GerbilResourceLoader ...
[snip]

okay, so right now i'm pretty well down to considering 2 solutions.  the 
first would be just defining all our old tags to be macros and placing them 
in vm libraries.  

the second would be a macro that simulates the behaviour i was looking for in 
#parse (thanks, bill burton):

<table>
   #foreach($i in $iterate)
      ## Generic way to specify named parameters
      #set($params = [ "param1=$bar1", "param2=$bar2" ])
      ## The #parsetag macro calls a helper tool in the context 
      ## to parse parameter names out of the $params ArrayList 
      ## putting them into the Context.  It then calls #parse.
      #parsetag("foo.vm" $params)
   #end
</table>

so the question i pose to the list now is, which of these methods would bear 
the least expense at run time?  

bearing in mind that we have around 400 tags in production at all times, 
(that is, 4 sites each with ~40 for layout, and about 100 distinct templates 
each with 2 or 3 for data) with edits being made and new tags installed 
daily, our macro library files would be fairly large and updated quite often. 
 does performance using macro libs degrade when they reach sizes like this?  
how does the caching work with a macro in a library?  if a template 
containing one of these macros is cached, is the library rechecked every time 
the template is used?  

the second solution seems to be more costly every time it's used, as (i 
assume) it redefines the macro used by foo.vm every time foo.vm is parsed.  

if runtime efficiency were even, i'd like to go with sol. 1 (the libraries), 
as it is the most intuitive for developers compared to what we currently 
have.  if anyone can give me reason why its a bad solution though, i'd 
appreciate hearing it now.

thanks much,
--darin

-- 
Darin Kelkhoff
darink@sportingnews.com
Programmer
The Sporting News
www.sportingnews.com

Re: passing parameters to #parse'ed files0

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 10/22/01 12:36 PM, "Darin Kelkhoff" <da...@sportingnews.com> wrote:

> On Sunday 21 October 2001 11:11 pm, you wrote:
>> On 10/19/01 2:28 PM, "Darin Kelkhoff" <da...@sportingnews.com> wrote:

[SNIP]

>> 
>> I read below, and what I don't understand is why you can't just use
>> libraries of Velocimacros to do this.
>> 
>> I mean, you are looking for parameterized tag replacement anyway, right?
>> 
>> From what I gather, the old system is
>> 
>> <table>
>>   {LOOP}
>>        <Tag w/  param>
>>   {/LOOP}
>> </table>
> 
> the old system can be <tag w/ param> or just <tag> without param.  one of my
> goals was to keep the use the same whether a param was needed or not.  also,
> one of the earlier decisions i had made on calling <tag> without params was
> to just make a call to #parse, so that each "tag" would be in its own file
> and still easily managed by a designer.  we have about 500 tags being used in
> production right now, with development occurring all the time on them.  (that
> is, every day new ones introduced and old ones edited).

That's 500 tag files.   Hm.

I can think of a few solutions.  Velocity is pretty adaptable.  I would
think that you will get away from this at some point :)

One way is to make each tag a VM in the following way :

#macro( foo )

  foo stuff

#end

#foo()


This isn't the most efficent thing, but it means that you can both use it as
a library, and #parse() it

The advantage is you can have programmatic tag management - on startup, have
a routine setup the list of library files (every .vm in a 'tag' directory),
and add that directory to the template path.

Then, you can either invoke them as VMs or #parse() them.

I would hope you could encourage people to just invoke though.

> 
>> Why is the VM solution below different that that of your parameterized
>> tags?
>> 
>> <table>
>>   #foreach( $item in $itemset )
>>      #foo( $item.foo $item.bar )
>>   #end
>> </table>
>> 
>> (or whatever you do to get params)
>> 
>> This seems a direct parallel to your tag approach.
>> 
>> What are the drawbacks of this for you?
> 
> so, if we would have all our old "tag"'s now exist as macros in a macro
> library file.  good, then we would still have a consistent calling method
> (whether or not params were needed).  i guess the only trick now is the
> management of the vm library file(s).  we can have as many as we want,
> correct? 

Yes.  They don't even have to be in a file, technically.  Could come from
anywhere, like a jar, database or gerbil, assuming you write a
GerbilResourceLoader ...


> i guess i see 2 issues:   1, several developers will need to be
> working in the library simultaneously, and 2, the library will need to be
> cached by Velocity when possible, but reloaded when necessary (which is
> fairly frequent).

Velocity can autoreload changed VMs now in development mode (you don't want
to do this in production...)

Second, if you make it programmatic when the engine starts up, you can do
something like load these from a database too...

There are bunches of options here, but note that they aren't run of the mill
- you don't have a run-of-the-mill problem.

But I think it's doable and manageable, at least for what I have in mind.


> as far as 1, i can see us either cvs controlling the file, or more likely
> abstracting out the library file, having it be reconstructed when our
> preprocessor installs a new vm into our system.  (this one won't be a
> problem).
> 

Ok.

> for 2, i've noted the property "velocimacro.library.autoreload" in the
> developer-guide, but we may need to circumvent this behavior in our custom
> resource loader.  are vm library files handled by the resource loader,
> somethign that we will have control over?

You will share control with the VM management system - when that's on, it
will see if the library file a given VM comes from has changed when someone
accesses that VM in a template.  The loader tells the manager if the source
of that VM has changed - if so, the VM manager loads it using the normal
loader interface.

So yes, you can have some good visibility into this process from the POV of
the loader.

> 
> also, i don't think i've found a sample of a velocimacro library file
> anywhere in the docs... am i missing it?

It's a regular template.

#macro(foo)
  foo
#end

No different than anything else - you can list multiple macros... You can
have multiple files... Very simple.  We are a simple people, here in
Velocityland.

I will note that in the docs.  :)

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



Re: passing parameters to #parse'ed files0

Posted by Darin Kelkhoff <da...@sportingnews.com>.
On Sunday 21 October 2001 11:11 pm, you wrote:
> On 10/19/01 2:28 PM, "Darin Kelkhoff" <da...@sportingnews.com> wrote:
> > hello, list,
> >
> > i'm getting ready to work on a project, porting my company's templating
> > development from a proprietary vendor product to velocity.
>
> Yay!
>
> > I'll be
> > responsible for determining exactly how velocity will be used by the
> > other programmers and designers here, and i'm trying to make this
> > transition as easy as possible for all the other team members (lower the
> > learning curve: i'm not worried about the velocity syntax being tough to
> > learn,
>
> I would hope not.
>
> > just that if
> > we have to change our way of thinking about templates too much, that
> > would be harder to learn.)
>
> Yep.
>
> > one fairly major component of our old system that i'm not sure how to
> > convert into velocity is the user-defined tags that take formal
> > parameters in our old system.  it seems obvious that in all our old
> > templates when we made calls to user-defined tags, that those could just
> > be replaced now with calls to #parse() other template files (for some
> > encapsulation of common code, etc). the problem is that our old system
> > let us pass parameters into these tags, and i don't think that i can do
> > that using #parse().
>
> I read below, and what I don't understand is why you can't just use
> libraries of Velocimacros to do this.
>
> I mean, you are looking for parameterized tag replacement anyway, right?
>
> From what I gather, the old system is
>
> <table>
>   {LOOP}
>        <Tag w/  param>
>   {/LOOP}
> </table>

the old system can be <tag w/ param> or just <tag> without param.  one of my 
goals was to keep the use the same whether a param was needed or not.  also, 
one of the earlier decisions i had made on calling <tag> without params was 
to just make a call to #parse, so that each "tag" would be in its own file 
and still easily managed by a designer.  we have about 500 tags being used in 
production right now, with development occurring all the time on them.  (that 
is, every day new ones introduced and old ones edited).


> Why is the VM solution below different that that of your parameterized
> tags?
>
> <table>
>   #foreach( $item in $itemset )
>      #foo( $item.foo $item.bar )
>   #end
> </table>
>
> (or whatever you do to get params)
>
> This seems a direct parallel to your tag approach.
>
> What are the drawbacks of this for you?

so, if we would have all our old "tag"'s now exist as macros in a macro 
library file.  good, then we would still have a consistent calling method 
(whether or not params were needed).  i guess the only trick now is the 
management of the vm library file(s).  we can have as many as we want, 
correct?  i guess i see 2 issues:   1, several developers will need to be 
working in the library simultaneously, and 2, the library will need to be 
cached by Velocity when possible, but reloaded when necessary (which is 
fairly frequent).  

as far as 1, i can see us either cvs controlling the file, or more likely 
abstracting out the library file, having it be reconstructed when our 
preprocessor installs a new vm into our system.  (this one won't be a 
problem).

for 2, i've noted the property "velocimacro.library.autoreload" in the 
developer-guide, but we may need to circumvent this behavior in our custom 
resource loader.  are vm library files handled by the resource loader, 
somethign that we will have control over?

also, i don't think i've found a sample of a velocimacro library file 
anywhere in the docs... am i missing it?  

thanks,


> I agree that your solution1 is bad below - however it's not even an analog
> to the 'old way', as you are doing the #parse() outside of the loop - and I
> agree that solution 2 is error prone.
>
> Note that this was one of the motivating reasons for VMs - so designers
> could have parameterized 'subroutines' of view layer 'stuff' to work with.
>
> Let us know.
>
> geir
>
> > Old system:
> > ------------
> > <table>0
> >  <? ITERATION CONSTRUCT ?>
> >     <? foo-tag param1=$bar1 param2=$bar2 ?>
> >  <? END ITERATION ?>
> > </table>
> >
> >
> > What we'd like w/ velocity:
> > ---------------------------
> > <table>
> >  #foreach($i in $iterate)
> >     ## foo.vm takes 2 parameters (named param1 & param2)
> >     #parse("foo.vm" $bar1 $bar2)
> >  #end
> > </table>
> >
> > i can see a few potential solutions, but none of them are quite as slick
> > as I'd like to make things.  first of all, i could make a rule that if a
> > #parse'd file needed parameters, that it would have to just define a
> > macro, which would then be called with the parameters after it was
> > #parse'd, similar to this:
> >
> > Solution 1:
> > -----------
> > ## foo.vm defines #foo-macro
> > #parse("foo.vm")
> > <table>
> >  #foreach($i in $iterate)
> >     ## foo-macro takes 2 parameters (named param1 & param2)
> >     #foo-macro($bar1 $bar2)
> >  #end
> > </table>
> >
> > two reasons i don't like this approach are that 1.) it changes what we
> > are currently doing, by having to #parse and then #foo-macro, and 2.) it
> > causes us to have 2 different ways of using #parse (the normal approach,
> > just to include the html (and vtl) in a file, and 2 to include a macro in
> > the file, only for that macro to be called later).
> >
> > the second possible solution i see would be for each file that gets
> > #parse'd, that if it needed parameters, they would have to be #set before
> > the file got #parse'd.  similar to this:
> >
> > Solution 2:
> > -----------
> > <table>
> >  #foreach($i in $iterate)
> >     #set($param1 = $bar1)
> >     #set($param2 = $bar2)
> >     ## foo.vm depends on $param1 and $param2 to be set
> >     #parse("foo.vm")
> >  #end
> > </table>
> >
> > the problem here is that it requires everyone who uses foo.vm to have to
> > know exactly what parameters it expects.   Also, the designers would have
> > to know to set these params in the context, can have to no not to
> > overwrite current values, there are all kindsa problems with this
> > solution.
> >
> > a third solution has been mentioned is that we could fake passing
> > parameters with #parse ourselves, as we are planning on having all our
> > templates run through some sort of "preprocessor" anyway when they are
> > moved from development into testing (for now, just responsible for some
> > syntax checking and file moving).  i'm not sure if this sounds like a
> > decent idea, or how workable this would be, but i guess it is another
> > option.
> >
> > has anyone else ever thought about doing this?  how are similar issues
> > handled in other places?  should i just make some files be #parsed, and
> > others be #parse'd and then #macro-call'd ?
> >
> > thanks for any help, and sorry for my verbosity.
> > --darin

-- 
Darin Kelkhoff
darink@sportingnews.com
Programmer
The Sporting News
www.sportingnews.com

Re: passing parameters to #parse'ed files0

Posted by "Geir Magnusson Jr." <ge...@optonline.net>.
On 10/19/01 2:28 PM, "Darin Kelkhoff" <da...@sportingnews.com> wrote:

> hello, list,
> 
> i'm getting ready to work on a project, porting my company's templating
> development from a proprietary vendor product to velocity.

Yay!

> I'll be 
> responsible for determining exactly how velocity will be used by the other
> programmers and designers here, and i'm trying to make this transition as
> easy as possible for all the other team members (lower the learning curve:
> i'm not worried about the velocity syntax being tough to learn,

I would hope not.

> just that if 
> we have to change our way of thinking about templates too much, that would be
> harder to learn.)

Yep.
 
> one fairly major component of our old system that i'm not sure how to convert
> into velocity is the user-defined tags that take formal parameters in our old
> system.  it seems obvious that in all our old templates when we made calls to
> user-defined tags, that those could just be replaced now with calls to
> #parse() other template files (for some encapsulation of common code, etc).
> the problem is that our old system let us pass parameters into these tags,
> and i don't think that i can do that using #parse().
> 

I read below, and what I don't understand is why you can't just use
libraries of Velocimacros to do this.

I mean, you are looking for parameterized tag replacement anyway, right?

>From what I gather, the old system is

<table>
  {LOOP}
       <Tag w/  param>
  {/LOOP}
</table>

Why is the VM solution below different that that of your parameterized tags?

<table> 
  #foreach( $item in $itemset )
     #foo( $item.foo $item.bar )
  #end
</table>

(or whatever you do to get params)

This seems a direct parallel to your tag approach.

What are the drawbacks of this for you?


I agree that your solution1 is bad below - however it's not even an analog
to the 'old way', as you are doing the #parse() outside of the loop - and I
agree that solution 2 is error prone.

Note that this was one of the motivating reasons for VMs - so designers
could have parameterized 'subroutines' of view layer 'stuff' to work with.

Let us know.

geir


> Old system:
> ------------
> <table>0
>  <? ITERATION CONSTRUCT ?>
>     <? foo-tag param1=$bar1 param2=$bar2 ?>
>  <? END ITERATION ?>
> </table>
> 
> 
> What we'd like w/ velocity:
> ---------------------------
> <table>
>  #foreach($i in $iterate)
>     ## foo.vm takes 2 parameters (named param1 & param2)
>     #parse("foo.vm" $bar1 $bar2)
>  #end
> </table>
> 
> i can see a few potential solutions, but none of them are quite as slick as
> I'd like to make things.  first of all, i could make a rule that if a
> #parse'd file needed parameters, that it would have to just define a macro,
> which would then be called with the parameters after it was #parse'd, similar
> to this:
> 
> Solution 1:
> -----------
> ## foo.vm defines #foo-macro
> #parse("foo.vm") 
> <table>
>  #foreach($i in $iterate)
>     ## foo-macro takes 2 parameters (named param1 & param2)
>     #foo-macro($bar1 $bar2)
>  #end
> </table>
> 
> two reasons i don't like this approach are that 1.) it changes what we are
> currently doing, by having to #parse and then #foo-macro, and 2.) it causes
> us to have 2 different ways of using #parse (the normal approach, just to
> include the html (and vtl) in a file, and 2 to include a macro in the file,
> only for that macro to be called later).
> 
> the second possible solution i see would be for each file that gets #parse'd,
> that if it needed parameters, they would have to be #set before the file got
> #parse'd.  similar to this:
> 
> Solution 2:
> -----------
> <table>
>  #foreach($i in $iterate)
>     #set($param1 = $bar1)
>     #set($param2 = $bar2)
>     ## foo.vm depends on $param1 and $param2 to be set
>     #parse("foo.vm")
>  #end
> </table>
> 
> the problem here is that it requires everyone who uses foo.vm to have to know
> exactly what parameters it expects.   Also, the designers would have to know
> to set these params in the context, can have to no not to overwrite current
> values, there are all kindsa problems with this solution.
> 
> a third solution has been mentioned is that we could fake passing parameters
> with #parse ourselves, as we are planning on having all our templates run
> through some sort of "preprocessor" anyway when they are moved from
> development into testing (for now, just responsible for some syntax checking
> and file moving).  i'm not sure if this sounds like a decent idea, or how
> workable this would be, but i guess it is another option.
> 
> has anyone else ever thought about doing this?  how are similar issues
> handled in other places?  should i just make some files be #parsed, and
> others be #parse'd and then #macro-call'd ?
> 
> thanks for any help, and sorry for my verbosity.
> --darin
> 

-- 
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