问题
It seems that <@compress single_line=true> is replacing line breaks with single spaces (" "), instead of just suppressing them.
Example:
<@compress single_line=true>
"First cell"
<#if something >
|"Second cell"
</#if>
|"Third cell"
</@compress>
Is printing:
"First cell" |"Second cell" |"Third cell"
Which can't be parsed by a legacy system just because of the spaces between the pipes.
Is there any way to avoid this?, perhaps a way to read every "nested" line in a macro to substitute the functionality of @compress?
In the end, I don't want "structural source code", but presentation code, so assigning to variables to just print the result won't be nice.
Thank you in advance, kind regards.
回答1:
@compress
doesn't completely remove whitespace-regions because that would change the meaning of the output in almost all applications. @compress
itself is technically just a custom directive (that's why it uses @
instead of #
). Only it's always there for backward compatibility... So, yes, you can implement filters like that. You could implement TemplateDirectiveModel
(where you can use your own Writer
implementation to do the filtering) then drop it into the data-model, like, with name myCompress
. Or you can pull it into the template like #assign myCompress = 'com.example.MyCompressDirective'?new
, wherever you would use #macro
. In both cases, you could use it like <@myCompress>...</@myCompress>
.
Actually, you can solve this with a macro too. You can capture the generated output inside the macro with <#local captured><#nested></#local>
, then use regular expressions with ?replace
and such. It's just kind of ugly... filtering fits Java better. (Note that if the output_format
of the defining template is HTML
, XML
, etc., then you will need something like captured?markup_string?replace(...)?no_esc
. That is, you have to convert the captured markup to plain string, do the modifications on that, then convert it back to markup again.)
Note that you can also solve compression outside the template, if you pass a custom compressing Writer
to Template.process
.
回答2:
Thanks to @ddekany to answer this question. Next is the simple code that trims:
- Leading spaces (^\s+)
- Trailing spaces (\s+$)
- Line breaks (\n|\r)
Using regular expressions in multi-line mode ("rm" parameter)
You just need to remove any element on the expression to suit your needs, for example, if you just want to remove indentation, don't use 2 and 3 ;)
<#macro compress_single_line>
<#local captured><#nested></#local>
${ captured?replace("^\\s+|\\s+$|\\n|\\r", "", "rm") }
</#macro>
<@compress_single_line>
My free indented content
${ someVar }
</@compress_single_line>
Hope this complements helpfully @ddekany's answer.
回答3:
The following solution works also fine:
<#assign var>
"First cell"
<#if something >
|"Second cell"
</#if>
|"Third cell"
</#assign>
${var?replace("^\\s+|\\s+$|\\n|\\r", "", "rm")}
来源:https://stackoverflow.com/questions/21102122/freemarker-compress-single-line-without-spaces