The parser used by ?interpet and ?eval inherits not only the output_format of its surrounding lexical context, but also the auto-escaping policy of it (basically, if auto-escapig is on or off). Also documented how these built-ins inherit the configuration settings.
Project: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/commit/90fcfb9d Tree: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/tree/90fcfb9d Diff: http://git-wip-us.apache.org/repos/asf/incubator-freemarker/diff/90fcfb9d Branch: refs/heads/master Commit: 90fcfb9d7a6b859894ca27886ef7bd43c29cb8a8 Parents: d3654bc Author: ddekany <[email protected]> Authored: Sun Dec 27 15:54:31 2015 +0100 Committer: ddekany <[email protected]> Committed: Sun Dec 27 15:54:31 2015 +0100 ---------------------------------------------------------------------- .../freemarker/core/BuiltInsForStringsMisc.java | 3 +- src/main/java/freemarker/core/Interpret.java | 3 +- .../core/OutputFormatBoundBuiltIn.java | 4 +- ..._ParserConfigurationWithInheritedFormat.java | 10 ++-- src/main/javacc/FTL.jj | 2 +- src/manual/en_US/book.xml | 49 ++++++++++++++------ .../java/freemarker/core/OutputFormatTest.java | 22 +++++++++ 7 files changed, 69 insertions(+), 24 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/main/java/freemarker/core/BuiltInsForStringsMisc.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/BuiltInsForStringsMisc.java b/src/main/java/freemarker/core/BuiltInsForStringsMisc.java index 8b83c2c..3d21c0a 100644 --- a/src/main/java/freemarker/core/BuiltInsForStringsMisc.java +++ b/src/main/java/freemarker/core/BuiltInsForStringsMisc.java @@ -72,7 +72,8 @@ class BuiltInsForStringsMisc { ParserConfiguration pCfg = parentTemplate.getParserConfiguration(); // pCfg.outputFormat is exceptional: it's inherited from the lexical context if (pCfg.getOutputFormat() != outputFormat) { - pCfg = new _ParserConfigurationWithInheritedFormat(pCfg, outputFormat, null); + pCfg = new _ParserConfigurationWithInheritedFormat( + pCfg, outputFormat, Integer.valueOf(autoEscapingPolicy)); } FMParser parser = new FMParser( http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/main/java/freemarker/core/Interpret.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/Interpret.java b/src/main/java/freemarker/core/Interpret.java index 0b947ef..01d2a80 100644 --- a/src/main/java/freemarker/core/Interpret.java +++ b/src/main/java/freemarker/core/Interpret.java @@ -86,7 +86,8 @@ class Interpret extends OutputFormatBoundBuiltIn { ParserConfiguration pCfg = parentTemplate.getParserConfiguration(); // pCfg.outputFormat is exceptional: it's inherited from the lexical context if (pCfg.getOutputFormat() != outputFormat) { - pCfg = new _ParserConfigurationWithInheritedFormat(pCfg, outputFormat, null); + pCfg = new _ParserConfigurationWithInheritedFormat( + pCfg, outputFormat, Integer.valueOf(autoEscapingPolicy)); } interpretedTemplate = new Template( (parentTemplate.getName() != null ? parentTemplate.getName() : "nameless_template") + "->" + id, http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/main/java/freemarker/core/OutputFormatBoundBuiltIn.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/OutputFormatBoundBuiltIn.java b/src/main/java/freemarker/core/OutputFormatBoundBuiltIn.java index b32617b..2bcc106 100644 --- a/src/main/java/freemarker/core/OutputFormatBoundBuiltIn.java +++ b/src/main/java/freemarker/core/OutputFormatBoundBuiltIn.java @@ -25,10 +25,12 @@ import freemarker.template.utility.NullArgumentException; abstract class OutputFormatBoundBuiltIn extends SpecialBuiltIn { protected OutputFormat outputFormat; + protected int autoEscapingPolicy; - void bindToOutputFormat(OutputFormat outputFormat) { + void bindToOutputFormat(OutputFormat outputFormat, int autoEscapingPolicy) { NullArgumentException.check(outputFormat); this.outputFormat = outputFormat; + this.autoEscapingPolicy = autoEscapingPolicy; } @Override http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/main/java/freemarker/core/_ParserConfigurationWithInheritedFormat.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/core/_ParserConfigurationWithInheritedFormat.java b/src/main/java/freemarker/core/_ParserConfigurationWithInheritedFormat.java index ba21345..c479f45 100644 --- a/src/main/java/freemarker/core/_ParserConfigurationWithInheritedFormat.java +++ b/src/main/java/freemarker/core/_ParserConfigurationWithInheritedFormat.java @@ -22,19 +22,17 @@ import freemarker.template.Version; /** * For internal use only; don't depend on this, there's no backward compatibility guarantee at all! - * This class is to work around the lack of module system in Java, i.e., so that other FreeMarker packages can - * access things inside this package that users shouldn't. */ public final class _ParserConfigurationWithInheritedFormat implements ParserConfiguration { private final OutputFormat outputFormat; - private final Integer autoEscaping; + private final Integer autoEscapingPolicy; private final ParserConfiguration wrappedPCfg; public _ParserConfigurationWithInheritedFormat(ParserConfiguration wrappedPCfg, OutputFormat outputFormat, - Integer autoEscaping) { + Integer autoEscapingPolicy) { this.outputFormat = outputFormat; - this.autoEscaping = autoEscaping; + this.autoEscapingPolicy = autoEscapingPolicy; this.wrappedPCfg = wrappedPCfg; } @@ -67,7 +65,7 @@ public final class _ParserConfigurationWithInheritedFormat implements ParserConf } public int getAutoEscapingPolicy() { - return autoEscaping != null ? autoEscaping.intValue() : wrappedPCfg.getAutoEscapingPolicy(); + return autoEscapingPolicy != null ? autoEscapingPolicy.intValue() : wrappedPCfg.getAutoEscapingPolicy(); } public ArithmeticEngine getArithmeticEngine() { http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/main/javacc/FTL.jj ---------------------------------------------------------------------- diff --git a/src/main/javacc/FTL.jj b/src/main/javacc/FTL.jj index ad81e08..9c858e8 100644 --- a/src/main/javacc/FTL.jj +++ b/src/main/javacc/FTL.jj @@ -2128,7 +2128,7 @@ Expression BuiltIn(Expression lhoExp) : } if (result instanceof OutputFormatBoundBuiltIn) { - ((OutputFormatBoundBuiltIn) result).bindToOutputFormat(outputFormat); + ((OutputFormatBoundBuiltIn) result).bindToOutputFormat(outputFormat, autoEscapingPolicy); return result; } http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/manual/en_US/book.xml ---------------------------------------------------------------------- diff --git a/src/manual/en_US/book.xml b/src/manual/en_US/book.xml index 555c8e4..2745adb 100644 --- a/src/manual/en_US/book.xml +++ b/src/manual/en_US/book.xml @@ -17570,10 +17570,10 @@ Sorted by name.last: built-ins</link> that refer to a loop variable that was created outside <literal><replaceable>s</replaceable></literal>.</para> - <para>The configuration settings that affect the expression parsing - (like syntax) are coming from the <literal>Configuration</literal> - object, not from template that invokes - <literal>eval</literal>.</para> + <para>Regarding the configuration settings that affect the parsing + (like syntax) and evaluation the rules are the same as with the + <link linkend="ref_builtin_interpret"><literal>interpret</literal> + built-in</link>.</para> </section> <section xml:id="ref_builtin_has_content"> @@ -17637,16 +17637,6 @@ Sorted by name.last: user-defined directive that, when executed, runs the template whose content is the value of <literal>templateSource</literal>.</para> - <para>The configuration settings that affect the parsing (like tag - syntax and naming convention) are coming from the - <literal>Configuration</literal> object, not from template that - calls <literal>interpret</literal>. This also means that the - previously auto-detected tag syntax or auto-detected naming - convention doesn't effect the parsing of the interpreted template. - This is consistent with how the <link - linkend="ref_directive_include"><literal>include</literal> - directive</link> works.</para> - <para>The name of the template created by <literal>interpret</literal> is the name of the template that calls <literal>interpret</literal>, plus @@ -17673,6 +17663,29 @@ Sorted by name.last: a sequence of two items, in which case the first item is the FTL string to interpret, and the second items is the template name used after the <literal>"->"</literal>.</para> + + <para>The configuration settings that affect the interpreted + template are the same as of the surrounding template, except that + parser settings specified in the <link + linkend="ref.directive.ftl"><literal>ftl</literal> directive</link> + or was established via tag syntax or naming convention + auto-detection are instead coming from the + <literal>Configuration</literal> object (or naturally, from the + <link + linkend="pgui_config_templateconfigurations"><literal>TemplateConfiguration</literal></link>, + if there's any). Thus the tag syntax, naming convention, whitespace + handling, etc. of the interpreted template is independent of that + established <emphasis>inside</emphasis> the surrounding template. An + important exception from this rule is that the <link + linkend="dgui_misc_autoescaping_outputformat">output format</link> + and auto-escaping policy is inherited from the lexical context where + <literal>interpret</literal> is called from. For example in a + template that has <literal><#ftl + output_format="XML"></literal> header (or if you are inside a + <literal><#output_format + "XML"><replaceable>...</replaceable></#output_format></literal> + block), <literal>interpret</literal> calls in it will produce + directives with XML output format.</para> </section> <section xml:id="ref_builtin_isType"> @@ -27219,6 +27232,14 @@ TemplateModel x = env.getVariable("x"); // get variable x</programlisting> </listitem> </itemizedlist> </listitem> + + <listitem> + <para>The parser used by <literal>?interpet</literal> and + <literal>?eval</literal> inherits not only the + <literal>output_format</literal> of its surrounding lexical + context, but also the auto-escaping policy of it (basically, if + auto-escapig is on or off).</para> + </listitem> </itemizedlist> </section> </section> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/90fcfb9d/src/test/java/freemarker/core/OutputFormatTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/freemarker/core/OutputFormatTest.java b/src/test/java/freemarker/core/OutputFormatTest.java index cc31920..dc5e7d4 100644 --- a/src/test/java/freemarker/core/OutputFormatTest.java +++ b/src/test/java/freemarker/core/OutputFormatTest.java @@ -868,10 +868,32 @@ public class OutputFormatTest extends TemplateTest { + "<#outputFormat 'XML'>" + commonFTL + "</#outputFormat>", "Eval: RTF; Interpret: RTF \\{&\\}\n" + "Eval: XML; Interpret: XML {&}"); + + // parser.autoEscapingPolicy is inherited too: + assertOutput( + "<#ftl autoEsc=false outputFormat='XML'>" + + commonFTL + " ${'.autoEsc'?eval?c}", + "Eval: XML; Interpret: XML {&} false"); + assertOutput( + "<#ftl outputFormat='XML'>" + + "<#noAutoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#noAutoEsc>", + "Eval: XML; Interpret: XML {&} false"); assertOutput( "<#ftl autoEsc=false outputFormat='XML'>" + "<#noAutoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#noAutoEsc>", + "Eval: XML; Interpret: XML {&} false"); + assertOutput( + "<#ftl autoEsc=false outputFormat='XML'>" + + "<#autoEsc>" + commonFTL + " ${'.autoEsc'?eval?c}</#autoEsc>", "Eval: XML; Interpret: XML {&} true"); + assertOutput( + "${.outputFormat}<#assign ftl='<#ftl outputFormat=\\'RTF\\'>$\\{.outputFormat}'> <@ftl?interpret/>", + "undefined RTF"); + assertOutput( + "${.outputFormat}<#outputFormat 'RTF'>" + + "<#assign ftl='$\\{.outputFormat}'> <@ftl?interpret/> ${'.outputFormat'?eval}" + + "</#outputFormat>", + "undefined RTF RTF"); } @Test
