7

I've just learned that with apache velocity the directives add to the whitespace as well.

So for example:

#foreach ($record in $rows)
#foreach($value in $record)
$value  
#end

#end

With something like this I end up getting extra lines for the #foreach statements, the #end statements, etc.

This isn't what I want, so I found I could block comment at the end of the lines like so:

#foreach ($record in $rows)#*
*##foreach($value in $record)#*
*#$value    #*
*##end

#end

But this is pretty ugly to read. Is there any way to tell the velocity engine to not format my directives?

Maybe I'm doing something else wrong?

Thanks.

javamonkey79
  • 17,443
  • 36
  • 114
  • 172
  • That's one thing that's always annoyed me with Velocity - I use it to generate Java, so I can just format it in my IDE after generation. JET (Java emitter templates) doesn't seem to suffer from this problem. – James Bassett Dec 13 '11 at 21:31
  • It seems to be something people put up with and tidy up later, e.g. this [SO question](http://stackoverflow.com/questions/2277494/need-a-java-based-html-prettifier-to-clean-up-velocity-generated-html) regarding tidying HTML after generation. – James Bassett Dec 13 '11 at 21:38
  • Hmm, that sucks. I suppose my "work around" will have to do then. – javamonkey79 Dec 13 '11 at 23:07
  • What version are you using? This has been a *long*-running issue, bordering on 5-8 years now. There's [this](http://wiki.apache.org/velocity/StructuredGlobbingResourceLoader) now, which may or may not be what you need. Block comments or EOL `##` comments are the canonical solution – Dave Newton Dec 13 '11 at 23:36
  • That link is interesting...especially the _schmoo_ part...???!!! – James Bassett Dec 14 '11 at 00:17
  • Similar question: http://stackoverflow.com/questions/8594022/how-can-i-trim-whitespace-by-velocity – Vadzim Jun 25 '15 at 14:42

2 Answers2

4

I think you're stuck with it (see Velocity Whitespace Gobbling article) although line comments would be a little tidier:

#foreach ($record in $rows)##
#foreach($value in $record)##
$value    ##
#end

#end

Or you could just squeeze everything onto one line:

#foreach($record in $rows)#foreach($value in $record)${value}#{end}#{end}
Edd
  • 8,402
  • 14
  • 47
  • 73
  • The ## doesn't work for me. Only putting my macros on one single line works. Any ideas why this would be? – El Guapo Apr 29 '16 at 14:18
1

This is actually common to almost all templating languages and the reasoning comes directly from simplified processing. Consider the following example (this is actually GSP used by Grails but the idea is the same):

<g:each var="x" in="exes">
    ${x.y}
</g:each>

The way this is processed is that first a tag (or in Velocity's case, directive) is identified. Because the tag/directive itself contains instructions for processing the tag's body, the tag/directive marks are removed and all the content immediately after the starting mark and immediately before the ending mark is used as the target for the processing. This includes all the whitespace, because cleaning the output beforehand would be a lot more difficult.

This of course doesn't mean that you can't do it, as Edd points out or that this would be the most sensible design choice in the first place, but sometimes doing things more simply is more important than generating beautiful markup - after all, most if not all markup processors don't really care if you have <p>some\ncontent</p> or <p>some\n\n\n\t\tcontent</p>.

Esko
  • 29,022
  • 11
  • 55
  • 82