Very interesting work!
About the different alternatives - none of them really pleases me.
There's another option: not allowing block macros to be used before they
are defined. Okay, you cannot make crossed reflexivity with block macros
without... is it such a big deal?
Claude
Le jeudi 24 janvier 2008 à 19:53 -0500, Raghu Rajah a écrit :
> Apologies for a delayed response on this thread. Was buried in some work for
> the past couple of weeks. Was able to spend some time on this past couple of
> days. Here's what I have,
>
> I have a working version of the blockmacro as discussed in this thread.
> Patch attached. Here's the trivial example,
>
> #blockmacro(html $style)
> <html style="$style">
> ${yield}
> </html>
> #end
>
>
> Block Macro Result
> #html("color:red")
> <body>Raghu</body>
> #end
>
> In broad brush strokes, here's what I did,
>
>
> - Modified the grammar to look for blockmacro and register just like the
> regular macro would.
> - Created a new proxy for this and dealt with creating this one for block
> macros.
>
> I am yet to finish up some things,
>
> - Making yield variable configurable
> - want to make the proxy class interceptable (I need this ability to
> intercept and manipulate content)
> - the default templatetests doesn't seem to be comparing with the cmps. Is
> there something I need to do special to make this work. If I replace the
> content of any existing content with garbage, the tests still pass. Would
> appreciate help in pointing me in the right direction here.
> - refactor my current tests to be in alignment with other tests within the
> project and add more complex tests.
>
> Bumped in to a catch though,
>
> - If the block macro is used before it is declared, I would have no idea if
> the macro is a LINE one or a BLOCK one. Currently, I am defaulting to LINE
> which will make template parsing fail. There are four alternatives, I can
> think of,
>
> OPTION-1: Put a 'do' after my parameters.
>
> #html("something") do
> #end
>
> Of course, 'do' could be optional, if html is defined already. The bad thing
> about this is it introduces new language semantics into VTL
>
> OPTION-2: Create a call semantic for blockmacros
>
> #callBlockMacro (html "something")
> #end
>
> Again the callBlockMacro is optional, if you have defined html already.
>
> OPTION-3:Forward declaration for block macros.
>
> #forwardBlock html
> #forwardLine strong
>
> OPTION-4 (My preference): A configurable convention on prefix & suffix
> (thank you, Conor, for the suggestion)
>
> Blockmacro.default.prefix = _
>
> Recommendations, alternate suggestions, would be appreciated.
>
> Thanks,
> Raghu.
>
>
>
> On 1/7/08 11:48 AM, "Will Glass-Husain" <[EMAIL PROTECTED]> wrote:
>
> > Not quite sure if I follow how this would work. I'm guessing you'll
> > have to do some tricks with the parser nodes to make this work (since
> > at parse time the repository of macros is not yet defined). There's
> > probably a couple of ways of structuring this.
> >
> > Look forward to seeing some code. Thanks again for your interest in
> > contributing!
> >
> > WILL
> >
> > On Jan 7, 2008 8:35 AM, Claude Brisson <[EMAIL PROTECTED]> wrote:
> >> That does make sense. Thanks.
> >>
> >>> Since I would have the
> >>> repository of the defined velocimacros already, I can easily determine if
> >>> the current macro is a block.
> >>
> >> That is the specific point I was missing in your approach. Looks totally
> >> feasible.
> >>
> >>
> >> Claude
> >>
> >> Le lundi 07 janvier 2008 à 10:29 -0500, Raghu Rajah a écrit :
> >>
> >>> Maybe we are talking two different things.
> >>>
> >>> 1. I don't intend to distinguish the content variable (yield or
> >>> bodyContent)
> >>> from any other reference. It is just another reference as far as the
> >>> parser
> >>> is concerned. The only variation is in the proxy directive, which would
> >>> wrap
> >>> the context to add the capability to yield (trap get on "yield" and render
> >>> content in-place).
> >>>
> >>> 2. I did not intend to add the block-macros as part of the parsing
> >>> environment. The parser will treat the block macro usage as yet another
> >>> velocimacro, this one just happens to be a block. Since I would have the
> >>> repository of the defined velocimacros already, I can easily determine if
> >>> the current macro is a block. All the Parser does here is to add the
> >>> content
> >>> as the child of the current AST, as opposed to a peer.
> >>>
> >>> 3. The real problem is to distinguish during definition if a macro is a
> >>> block-macro or a single-line one. Since there is no begin syntax for the
> >>> block I (as the parser) won't know for sure if the next line is a
> >>> beginning
> >>> of a block or simply another peer node. Which is why I need a new
> >>> directive
> >>> "#block"
> >>>
> >>> Does this make sense? Let me know what you feel about this.
> >>>
> >>> Raghu.
> >>>
> >>>
> >>> On 1/7/08 9:52 AM, "Claude Brisson" <[EMAIL PROTECTED]> wrote:
> >>>
> >>>> Le lundi 07 janvier 2008 à 07:34 -0500, Raghu Rajah a écrit :
> >>>>> Actually, I was saying the opposite. We can keep the calling semantics,
> >>>>> as
> >>>>> is. I might have to use an alternate directive (other than #macro) for
> >>>>> definition.
> >>>>> The definition parsing would become non-deterministic otherwise
> >>>>
> >>>> I don't agree, or maybe I don't understand. In the definition code,
> >>>> block macros [may] make use of a specific reference that contains the
> >>>> block itself. At parsing time, nothing makes this reference different
> >>>> from the others, that is, $yield or $bodyContent or whatever you call it
> >>>> is just a reference with no specific meaning from the parser point of
> >>>> view. How comes you would want to introduce a difference here? Why do
> >>>> you see it as introducing a non-deterministic behaviour?
> >>>>
> >>>>> We already have block handling for directives within the parser grammar,
> >>>>> that I can overload for handling block macro usage as well.
> >>>>
> >>>> Standard and custom directives, that alter the behaviour of the parser,
> >>>> are defined prior to any parsing. We shall call this the parsing
> >>>> environment. Macros are not part of this environment since they are
> >>>> defined in parsed files. What I do call determinism in this context is
> >>>> the fact that in a specific parsing environment, every file can be
> >>>> parsed independantly from the others.
> >>>>
> >>>> I may be wrong but I think that your proposal implies that block
> >>>> directives be defined only in a preloaded velocimacro library,
> >>>> conceptually making the library part of the parsing environment if you
> >>>> want to be able to state that the parsing is deterministic. it means
> >>>> that block macros cannot be defined inline. I'm not stricly opposed to
> >>>> it, but I think it'd be easier to use an alternate syntax so that block
> >>>> macro definitions don't have to be predefined prior to the parsing
> >>>> stage, and can be defined inline.
> >>>>
> >>>>
> >>>> Claude
> >>>>
> >>>>> On Will's suggestion, I personally would prefer to keep the calling
> >>>>> semantics between #macro and #blockmacro (or #block) the same. That
> >>>>> would
> >>>>> give us interesting opportunities to genericize the VTL language in the
> >>>>> future (if we can address the block-breaking structure like elseif) and
> >>>>> perhaps provide support for alternate DSLs.
> >>>>>
> >>>>> I prefer "yield" too. I will stick with that for the moment. Should be
> >>>>> an
> >>>>> easy one to change if there is disagreement over it
> >>>>>
> >>>>> Thanks,
> >>>>> Raghu.
> >>>>>
> >>>>> On 1/7/08 6:22 AM, "Claude Brisson" <[EMAIL PROTECTED]> wrote:
> >>>>>
> >>>>>> Yes, Raghu, I'm "+1" if we find a mean of implementing it and agree
> >>>>>> about the syntax.
> >>>>>>
> >>>>>> It's the use of the macro that should be differenciated between block
> >>>>>> and non-block versions, not definition (for definition, I guess we can
> >>>>>> keep #macro), for the parsing process to be deterministic.
> >>>>>>
> >>>>>> It looks like using a special directive to call the macro -as Will
> >>>>>> suggests- is the only way to go. And yes, block macros should having
> >>>>>> both a body and (a variable number of) arguments.
> >>>>>>
> >>>>>> #call? #block? #blockmacro? I like #block.
> >>>>>>
> >>>>>> #block(onemacro) without arg #end
> >>>>>> #block(anothermacro,$arg1) only one arg #end
> >>>>>> #block(themacro,$arg1,$arg2) etc... #end
> >>>>>>
> >>>>>> Concerning the name of the reference holding the body: it should anyway
> >>>>>> be made configurable. $bodyContent looks heavier than $yield but much
> >>>>>> more explicit.
> >>>>>>
> >>>>>> Claude
> >>>>>>
> >>>>>> Le dimanche 06 janvier 2008 à 21:18 -0800, Will Glass-Husain a écrit :
> >>>>>>> I like this idea. Similar to JSP tags that have attributes and body.
> >>>>>>>
> >>>>>>> Question--- would a block macro be able to have both arguments and a
> >>>>>>> body? I'd think this would be useful.
> >>>>>>>
> >>>>>>> Second, to clarify Claude's point about the difficulty. The issue is
> >>>>>>> that the parser needs to call the block-macro, but since the actual
> >>>>>>> macro is defined at run-time, the parser doesn't know whether to call
> >>>>>>> a regular macro (no #end required) a block macro (needs an end) or
> >>>>>>> just pass through verbatim (e.g. not defined macro). I guess to make
> >>>>>>> this work the parser would need to open up a macro node any time a
> >>>>>>> #abc() is included and just have all the following VTL be children.
> >>>>>>> (either to an #end statement or to the end of the file. Not sure if
> >>>>>>> this is workable, though it might be.
> >>>>>>>
> >>>>>>> An alternative would be to use a unique way of identifying block
> >>>>>>> macros that could be recognized by the parser. Maybe a special
> >>>>>>> directive to call the macro? In other words, to call the block macro
> >>>>>>> "strong" the syntax would be
> >>>>>>>
> >>>>>>> #call(strong)
> >>>>>>>
> >>>>>>> #end
> >>>>>>>
> >>>>>>> WILL
> >>>>>>>
> >>>>>>> On Jan 6, 2008 6:06 PM, Raghu Rajah <[EMAIL PROTECTED]> wrote:
> >>>>>>>> Nathan - Overloading #macro would be rather hard, especially since
> >>>>>>>> VTL
> >>>>>>>> does
> >>>>>>>> not have a begin token for blocks, the parser lookahead would become
> >>>>>>>> non-deterministic, I think. I can call the inner call "contentBody",
> >>>>>>>> "yield"
> >>>>>>>> is rather commonly used term for this purpose in the ruby world.
> >>>>>>>>
> >>>>>>>> Claude - Was that a +1? Trust you are a committer.
> >>>>>>>>
> >>>>>>>> Raghu.
> >>>>>>>>
> >>>>>>>>> Subject: Re: Blocks in Velocimacros
> >>>>>>>>> From: [EMAIL PROTECTED]
> >>>>>>>>> To: [email protected]
> >>>>>>>>> Date: Sun, 6 Jan 2008 23:39:43 +0100
> >>>>>>>>
> >>>>>>>>>
> >>>>>>>>> I agree, this would be useful. But since the parser would have to
> >>>>>>>>> know
> >>>>>>>>> macros definitions to detect blocks, I'm pretty sure it's very hard
> >>>>>>>>> to
> >>>>>>>>> implement.
> >>>>>>>>>
> >>>>>>>>> The way to go is the custom directive - that's much easier.
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> Claude
> >>>>>>>>>
> >>>>>>>>> Le dimanche 06 janvier 2008 à 14:13 -0800, Nathan Bubna a écrit :
> >>>>>>>>>> Yeah, i'm at least interested. If it works well and we have some
> >>>>>>>>>> good
> >>>>>>>>>> tests for it (and, of course, all existing tests pass), i would
> >>>>>>>>>> even
> >>>>>>>>>> support putting it into Velocity 1.6 (rather than wait for 1.7).
> >>>>>>>>>> We've already got a lot of macro improvements in, this would
> >>>>>>>>>> Though,
> >>>>>>>>>> i'd want the support of at least one other committer before doing
> >>>>>>>>>> that. I do have one question and one suggestion at this point:
> >>>>>>>>>> Would
> >>>>>>>>>> it work to overload the #macro directive instead of using
> >>>>>>>>>> #blockmacro?
> >>>>>>>>>> (Not that big a deal to me, but people will ask.) And i would
> >>>>>>>>>> suggest using $bodyContent as the default, instead of $yield since
> >>>>>>>>>> that is more familiar to people.
> >>>>>>>>>>
> >>>>>>>>>> This is a great idea though! People have talked about it, but no
> >>>>>>>>>> one
> >>>>>>>>>> has ever taken it upon themselves to work on it.
> >>>>>>>>>>
> >>>>>>>>>> On Jan 6, 2008 12:19 PM, Raghu Rajah <[EMAIL PROTECTED]> wrote:
> >>>>>>>>>>> If I offer to implement block support, is there any interest in
> >>>>>>>>>>> absorbing
> >>>>>>>>>>> this contribution into the codebase.
> >>>>>>>>>>>
> >>>>>>>>>>> Here's what I intend to do,
> >>>>>>>>>>>
> >>>>>>>>>>> 1. Add a new directive called "blockmacro", along the same lines
> >>>>>>>>>>> as
> >>>>>>>>>>> macro, subclassing behavior from the current macro processing both
> >>>>>>>>>>> in
> >>>>>>>>>>> the
> >>>>>>>>>>> directive and the JJT.
> >>>>>>>>>>> 2. In order to render the content of the block, one could use a
> >>>>>>>>>>> special
> >>>>>>>>>>> context variable called "yield", that could be customized as
> >>>>>>>>>>> whatever
> >>>>>>>>>>> in
> >>>>>>>>>>> the properties.
> >>>>>>>>>>>
> >>>>>>>>>>> The net definition would look something like,
> >>>>>>>>>>>
> >>>>>>>>>>> #blockmacro strong
> >>>>>>>>>>> <strong>${yield}</strong>
> >>>>>>>>>>> #end
> >>>>>>>>>>>
> >>>>>>>>>>> and usage would look like
> >>>>>>>>>>>
> >>>>>>>>>>> #strong
> >>>>>>>>>>> This is a strong text for #if (${user.male}) Mr. #else Ms. #end
> >>>>>>>>>>> ${user.name}.
> >>>>>>>>>>> #end
> >>>>>>>>>>>
> >>>>>>>>>>> Regards,
> >>>>>>>>>>> Raghu.
> >>>>>>>>>>>
> >>>>>>>>>>>> From: [EMAIL PROTECTED]
> >>>>>>>>>>>> To: [EMAIL PROTECTED]
> >>>>>>>>>>>> Subject: RE: Blocks in Velocimacros
> >>>>>>>>>>>> Date: Thu, 3 Jan 2008 17:49:07 -0500
> >>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> I think I will go the custom directive route.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Thanks for all the pointers. I especially like the Hacking
> >>>>>>>>>>>> Velocity
> >>>>>>>>>>>> presentation - rather groovy. It addresses nearly all the issues
> >>>>>>>>>>>> I
> >>>>>>>>>>>> had.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Raghu.
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Date: Thu, 3 Jan 2008 14:37:35 -0800
> >>>>>>>>>>>> From: [EMAIL PROTECTED]
> >>>>>>>>>>>> To: [EMAIL PROTECTED]
> >>>>>>>>>>>> Subject: Re: Blocks in Velocimacros
> >>>>>>>>>>>>
> >>>>>>>>>>>> Of course, you would then have to be sure to escape all "
> >>>>>>>>>>>> characters
> >>>>>>>>>>>> in your body content:
> >>>>>>>>>>>>
> >>>>>>>>>>>> #set( $Q = '"' )
> >>>>>>>>>>>>
> >>>>>>>>>>>> #myForm( "
> >>>>>>>>>>>> <!-- some ${Q}arbitrary${Q} -->
> >>>>>>>>>>>> " )
> >>>>>>>>>>>>
> >>>>>>>>>>>> so that you don't prematurely end your $body parameter. this is
> >>>>>>>>>>>> obviously not ideal, but may be easier than writing a custom
> >>>>>>>>>>>> directive, depending on the specifics of your case(s).
> >>>>>>>>>>>>
> >>>>>>>>>>>> On Jan 3, 2008 2:35 PM, Nathan Bubna <[EMAIL PROTECTED]> wrote:
> >>>>>>>>>>>> Also note that as of Velocity 1.5, you can include line breaks in
> >>>>>>>>>>>> strings, making it reasonable (though not as pretty to do
> >>>>>>>>>>>> something
> >>>>>>>>>>>> like:
> >>>>>>>>>>>>
> >>>>>>>>>>>> #macro( myForm $body )
> >>>>>>>>>>>> <form...>
> >>>>>>>>>>>> $body
> >>>>>>>>>>>> </form>
> >>>>>>>>>>>> #end
> >>>>>>>>>>>>
> >>>>>>>>>>>> #myForm("
> >>>>>>>>>>>> <!-- some arbitrary html here -->
> >>>>>>>>>>>> ")
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> On Jan 2, 2008 7:13 PM, Raghuram Rajah <[EMAIL PROTECTED]>
> >>>>>>>>>>>> wrote:
> >>>>>>>>>>>>
> >>>>>>>>>>>> Can I use a block within a velocimacro? Basically, I am trying to
> >>>>>>>>>>>> create a macro that will emit a XHTML tag with some javascript
> >>>>>>>>>>>> out.
> >>>>>>>>>>>> I
> >>>>>>>>>>>> would hate to create a begin macro and an end macro to accomplish
> >>>>>>>>>>>> this. That would be rather error prone.
> >>>>>>>>>>>>
> >>>>>>>>>>>> I would ideally like to do something like,
> >>>>>>>>>>>>
> >>>>>>>>>>>> #myForm(...)
> >>>>>>>>>>>> <!-- some arbitrary html here -->
> >>>>>>>>>>>> #end
> >>>>>>>>>>>>
> >>>>>>>>>>>> generating something like
> >>>>>>>>>>>>
> >>>>>>>>>>>> <form ....
> >>>>>>>>>>>> <!-- some arbitrary html here -->
> >>>>>>>>>>>> </form>
> >>>>>>>>>>>>
> >>>>>>>>>>>> Any suggestions would be greatly appreciated.
> >>>>>>>>>>>>
> >>>>>>>>>>>> Thanks,
> >>>>>>>>>>>> Raghu.
> >>>>>>>>>>>>
> >>>>>>>>>>>> _________________________________________________________________
> >>>>>>>>>>>> Share life as it happens with the new Windows Live.
> >>>>>>>>>>>> http://www.windowslive.com/share.html?ocid=TXT_TAGHM_Wave2_sharelif
> >>>>>>>>>>>> e_
> >>>>>>>>>>>> 122007
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> -------------------------------------------------------------------
> >>>>>>>>>>>> --
> >>>>>>>>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>>>>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>>>>>>>
> >>>>>>>>>>>>
> >>>>>>>>>>>> _________________________________________________________________
> >>>>>>>>>>>> i'm is proud to present Cause Effect, a series about real people
> >>>>>>>>>>>> making
> >>>>>>>>>>>> a difference.
> >>>>>>>>>>>> http://im.live.com/Messenger/IM/MTV/?source=text_Cause_Effect
> >>>>>>>>>>>
> >>>>>>>>>>> _________________________________________________________________
> >>>>>>>>>>> Watch "Cause Effect," a show about real people making a real
> >>>>>>>>>>> difference.
> >>>>>>>>>>> http://im.live.com/Messenger/IM/MTV/?source=text_watchcause
> >>>>>>>>>>
> >>>>>>>>>> ---------------------------------------------------------------------
> >>>>>>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>>>>>
> >>>>>>>>>
> >>>>>>>>>
> >>>>>>>>> ---------------------------------------------------------------------
> >>>>>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>>>>
> >>>>>>>>
> >>>>>>>> _________________________________________________________________
> >>>>>>>> Get the power of Windows + Web with the new Windows Live.
> >>>>>>>> http://www.windowslive.com?ocid=TXT_TAGHM_Wave2_powerofwindows_012008
> >>>>>>>
> >>>>>>>
> >>>>>>>
> >>>>>>
> >>>>>>
> >>>>>> ---------------------------------------------------------------------
> >>>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>>
> >>>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>>> ---------------------------------------------------------------------
> >>>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>>
> >>>>
> >>>>
> >>>> ---------------------------------------------------------------------
> >>>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>>
> >>>>
> >>>
> >>>
> >>>
> >>> ---------------------------------------------------------------------
> >>> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >>> For additional commands, e-mail: [EMAIL PROTECTED]
> >>>
> >>
> >>
> >> ---------------------------------------------------------------------
> >> To unsubscribe, e-mail: [EMAIL PROTECTED]
> >> For additional commands, e-mail: [EMAIL PROTECTED]
> >>
> >>
> >
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]