[ https://issues.apache.org/jira/browse/VELOCITY-600?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12603683#action_12603683 ]
Adrian Tarau commented on VELOCITY-600: --------------------------------------- context.localPut(hasNextName , i.hasNext()) creates anyway a new Boolean object :) Anyway, template syntax looks better with $velocityHasNext instead of $tool.isLast() + $tool.wrap($collection). > #foreach & velocityCount > ------------------------ > > Key: VELOCITY-600 > URL: https://issues.apache.org/jira/browse/VELOCITY-600 > Project: Velocity > Issue Type: Improvement > Components: Engine > Reporter: Adrian Tarau > Priority: Minor > Fix For: 1.5.1 > > > velocityCount = Used in the #foreach() directive, defines the string to be > used as the context key for the loop count. A template would access the loop > count as $velocityCount. > Knowing current version of the loop counter is very useful, but something is > missing. Very often, when you generate some content base on a > model(JavaScript code based on some UI model) you have the need to know if > this is the last time when the #foreach block will be executed or not. > Example > You have a collection of objects Property(bean with key, value fields) and > you want to generate a JavaScript object with them. The result should be like > this : > {id : 1 , name = "John", ...} > you can generate this with > { > #foreach($property in $properties) > $property.key : "$property.value" #if($velocityCount != > $properties.size()) , #end > #end > } > You can store $properties.size() of course outside the loop. > The template will be less verbose if I will have something like that. > #if($velocityHasNext) , #end. > Instead of saving only the counter, a new variable called velocityHasNext > whould be populated with the result of iterator.hasNext(). This is a minor > modification of current #foreach directive > while (!maxNbrLoopsExceeded && i.hasNext()) > { > // TODO: JDK 1.4+ -> valueOf() > context.localPut(counterName , new Integer(counter)); > context.localPut(hasNextName , i.hasNext()); <--- here is the > change > Object value = i.next(); > context.localPut(elementKey, value); > /* > * If the value is null, use the special null holder context > */ > if( value == null ) > { > if( nullHolderContext == null ) > { > // lazy instantiation > nullHolderContext = new NullHolderContext(elementKey, > context); > } > node.jjtGetChild(3).render(nullHolderContext, writer); > } > else > { > node.jjtGetChild(3).render(context, writer); > } > counter++; > // Determine whether we're allowed to continue looping. > // ASSUMPTION: counterInitialValue is not negative! > maxNbrLoopsExceeded = (counter - counterInitialValue) >= > maxNbrLoops; > } > also init should contain > public void init(RuntimeServices rs, InternalContextAdapter context, Node > node) > throws TemplateInitException > { > super.init(rs, context, node); > counterName = rsvc.getString(RuntimeConstants.COUNTER_NAME); > hasNextName = rsvc.getString(RuntimeConstants.HAS_NEXT_NAME); > counterInitialValue = > rsvc.getInt(RuntimeConstants.COUNTER_INITIAL_VALUE); > .... > } > This should help creating clear templates(and avoid some mistakes, sometime - > like using the wrong collection to test :) ). > Thanks. > -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]