Output formats works the same with both #function and #macro. What
causes the difference in your case is that you *call* another macro
from that function. You could call it from a macro as well with
similar conclusion, but you have printed the output directly there.
The output format of the body of the called macro is fixed on parse
time. Imagine it as if the parser (where parsing happens when the
template is first loaded, earlier than template execution), it
modifies ${foo} to ${foo?esc('HTML')} for you (it doesn't, but it's
something similar). It's not dynamic. It saves you typing and prevents
human errors exploitable for XSS attack. See also this from the page
your have linked:

  Basically, each position in a template has an associated output
  format, and as you saw above, it might not be the same everywhere in
  the template. This association sticks to the positions and won't
  change as the template executes. So if, for example, you call a
  macro from inside an outputformat block and the called macro is
  defined outside that block, it won't get the output format of it.
  Or, if you have a macro that's defined in a template with HTML
  output format, no mater from where you call it, that macro will
  always execute with HTML output format. This is like if you were
  coloring each characters of the template files by output format in
  the text editor, and then later when the templates are executed, it
  only considers the color of the statement being executed. This gives
  you firm control over the output format and hence escaping; you
  don't have to consider the possible execution paths that can lead to
  a point.

Also, I'm curious what use case do you have for dynamic escaping. I
mean, I see your example, why, in the real world do you need something
like that?


Monday, April 9, 2018, 2:44:36 PM, Riehemann, Michael wrote:

> Hi Freemarker Devs,
>
> I have a question about the Autoescaping and the outputformat,
> https://freemarker.apache.org/docs/dgui_misc_autoescaping.html
>
> Examplecode:
>
> <#ftl output_format="HTML">
>
> <#outputformat "plainText">
> <#function testFunction>
> <#local result><@testMacro /></#local>
> <#return result />
> </#function>
> </#outputformat>
>
> <#outputformat "plainText">
> <#macro testMacro>
> &
> </#macro>
> </#outputformat>
>
> Test Function: ${testFunction()}
> Test Macro: <@testMacro/>
>
> Output:
>
> Test Function: &amp;
> Test Macro: &
>
> It looks like outputformat is not working surrounding a function.
> The simplest fix is to add ?no_esc to the call:
> ${testFunction()?no_esc}
>
> But we have a lot of calls of this function and don't want to change all 
> templates.
>
> So I tried this code (without outputformat):
>
> <#ftl output_format="HTML">
>
> <#function testFunction>
> <#local result><@testMacro /></#local>
> <#return result />
> </#function>
>
> <#outputformat "plainText">
> <#macro testMacro>
> &
> </#macro>
> </#outputformat>
>
> Test Function: ${testFunction()}
> Test Macro: <@testMacro/>
>
> Output:
>
> Test Function: &
> Test Macro: &
>
> Why does it work without the ouputformat surrounding the function?
> Or maybe, why does the outputformat do the opposite to the function?
>
> Thank you,
> Michael Riehemann

-- 
Thanks,
 Daniel Dekany

Reply via email to