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: dev@velocity.apache.org > >>>>>>>>> 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]