Hello,
I am new to velocity, I am from the near webmacro world. :-)
I was thinking about migrating to Velocity.
And when I came to the VMs I found it interesting, but would like to
increment its expressive power now that I got tempted to use it.
The improvement goes subject to this question:
I would like to have access inside a VM to the body node of the macro's
callee, is it possible?
I am new to this, and I would like to accomplish it if it is possible. Is
there any guru that can help me out?
Any comments are welcome.
Here I describe what uses I would be giving to it, with examples, so that I
can explain myself.
for example:
code->
#macro( tostring $strvar )
#set ( $strvar = "$macro_body") ## this would do a kind of
Velocity.execute($current_context, new
stringwriter(req.get("$strvar")),macro_body_node)
#end
<-code
so when I use it:
code->
#tostring ( $mystrvar)
VM code here, with any statements, directives, etc.
#end
$mytool.write2File($mystrvar,"/vmexec_output.html")
<-code
I get the output of this block in a separate file.
It can be even more interesting:
code->
#macro( applyxsl $xslfile )
#tostring ($newvar)
$macro_body
#end
$mytool.applyxsl($newvar,$xslfile)
#end
#macro (CanAccess $resource)
#if ($currentUser.canAccess($resource) )
$macro_body
#else
access denied
#end
#end
<-code
so when I use it:
code->
#applyxsl ( "mystyle.xsl")
<somexml>
#canAccess("hello")
<menu url="hello.html">hello</menu>
#end
more xml mixed with velocity
</somexml>
#end
<-code
I get some parts of my html defined with custom tags that I transform with
my xsl of desire.
We can even have a macro that redirects output, or that makes a new loop
like structure, anything.
something like that:
code->
#macro( foreachother $looping $looper )
#foreach $looping in $looper
#if ($foreach_couter % 2 == 1)
$macro_body
#end
#end
#end
#set ($mylist = ['you','are','the','least','beauty' ] )
#foreachother ("word", $mylist)
$word
#end
##should output: "you the beauty"
<-code
Ofcourse this is not much usefull, but perhaps a conditional other than the
parity of the loop counter is usefull, so to have a while VM, or alike.
And this is a little complicated, a transformer like the XSL above but
instead of using XSLT transformations, uses a much more powerfull
trasformer: DVSL
code->
#macro( applydvsl $dvslfile )
#tostring ($newvar)
$macro_body
#end
#set ( $xml = $mytool.bulidXML($newvar) ) ##build a dom tree out
of the string output of the block execution by vm (executed only once).
##*
initialize a DVSL instance to process the xml with the current velocity
engine, and current context, and specify dvslfile to parse for the
transformation.
By the way, is DVSL thread safe to be used in a servlet?
*##
#set ( $dvsl_instance =
$mytool.initializeDVSL($current_velocity_engine_instace,$current_context,$dv
slfile) )
#set ($output = $mytool.newStringWriter()) ##create a new string
writer to pass to dvsl
$dvsl_instance.transform($xml,$output) ##apply the transformation
$output ##expose content after first parse of velocity transformed
into xml and then transformed/filtered/xml_document_oriented_execution by
DVSL
#end
applydvsl ( "mydvsltransformation.dvsl")
<xml>
<queryDB query="select * from departments" into="depts"/>
<show var="depts">
#if (currentUser.LikesToSeeIds()) {
<value name="id"><title>Department Identification
Number</title></value>
}
<value name="description"><title>Department Name</title></value>
</show>
</xml>
#end
<-code
and the dvsl file could be something like:
code->
#match("xml")
<div bgcolor="$currentUser.getFavoriteColor()"> ## this $currentUser
comes from the context of the caller vm file that executed the applydvsl
macro
$context.applyTemplates()
</div>
#end
#match("queryDB")
#set ($query = $node.valueOf('query') )
#set ($into = $node.valueOf('into') )
#set ( $context.put($into, $mytool.execQuery_AddToContext($query) ) )
#end
#match("show")
#set ( $resultSet = $context.get( $node.valueOf('var') ) )
<table>
<tr>
#foreach ($column in node.children() )
<th> $column.valueOf('title.text()') </th>
#end
</tr>
#foreach ($rs in $resultSet )
<tr>
#foreach ($column in node.children() )
<td> $rs.get($column.valueOf('name')) </th>
#end
</tr>
#end
</table>
#end
<-code
and the output could be:
<div bgcolor="blue">
<table>
<tr>
<th>Department Identification Number</th>
<th>Department Name</th>
</tr>
<tr>
<td>13333</td>
<td>Brain overflow department</td>
</tr>
<tr>
<td>99444</td>
<td>Psychomaniac department</td>
</tr>
</table>
</div>
I can go on forever... this $macro_body would give a lot of power.
I guess that a kind of workarround is possible now... it would be to have
the body of this macros separated in a different file, or put inside a
string somehow (by the way, how can I put a chunk of text with enters, etc
into a string with Velocity?) and then give this string to the macro, and
the macro would execute this string using Velocity tools. But, I beleave
that to have it integrated is much better. Also it gets parsed only once
into a Velocity Node for multiple executions.
I hope to have managed to explain myself, and that not too much english
errors have splitted out there along my message.
Best regards,
Dario.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]