blob: 93e0c9d127293b671c05ecca7a6f9a834da00822 [file] [log] [blame]
<!doctype html>
<!-- Generated by FreeMarker/Docgen from DocBook -->
<html lang="en" class="page-type-section">
<head prefix="og: http://ogp.me/ns#">
<meta charset="utf-8">
<title>Auto-escaping and output formats - Apache FreeMarker Manual</title>
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="format-detection" content="telephone=no">
<meta property="og:site_name" content="Apache FreeMarker Manual">
<meta property="og:title" content="Auto-escaping and output formats">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="https://freemarker.apache.org/docs/dgui_misc_autoescaping.html">
<link rel="canonical" href="https://freemarker.apache.org/docs/dgui_misc_autoescaping.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="https://fonts.googleapis.com/css?family=Roboto:500,700,400,300|Droid+Sans+Mono">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1707770044859">
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/cookie-bar/cookiebar-latest.min.js"></script>
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="https://freemarker.apache.org/docs/">
<meta itemprop="name" content="Apache FreeMarker Manual">
<!--[if lte IE 9]>
<div class="oldBrowserWarning" style="display: block">
Unsupported web browser - Use a modern browser to view this website!
</div>
<![endif]--> <div class="oldBrowserWarning">
Unsupported web browser - Use a modern browser to view this website!
</div>
<div class="header-top-bg"><div class="site-width header-top"><div id="hamburger-menu" role="button"></div> <div class="logo">
<a href="https://freemarker.apache.org" role="banner"><img itemprop="image" src="logo.png" alt="FreeMarker"></a> </div>
<ul class="tabs"><li><a href="https://freemarker.apache.org/">Home</a></li><li class="current"><a href="index.html">Manual</a></li><li><a class="external" href="api/index.html">Java API</a></li></ul><ul class="secondary-tabs"><li><a class="tab icon-heart" href="https://freemarker.apache.org/contribute.html" title="Contribute"><span>Contribute</span></a></li><li><a class="tab icon-bug" href="https://issues.apache.org/jira/projects/FREEMARKER" title="Report a Bug"><span>Report a Bug</span></a></li><li><a class="tab icon-download" href="https://freemarker.apache.org/freemarkerdownload.html" title="Download"><span>Download</span></a></li></ul></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">Manual</a><div class="navigation-header"></div><form method="get" class="search-form" action="search-results.html"><fieldset><legend class="sr-only">Search form</legend><label for="search-field" class="sr-only">Search query</label><input id="search-field" name="q" type="search" class="search-input" placeholder="Search" spellcheck="false" autocorrect="off" autocomplete="off"><button type="submit" class="search-btn"><span class="sr-only">Search</span></button></fieldset></form></div><div class="site-width breadcrumb-row"> <div class="breadcrumbs">
<ul class="breadcrumb" itemscope itemtype="http://schema.org/BreadcrumbList"><li class="step-0" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="index.html"><span itemprop="name">Apache FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui.html"><span itemprop="name">Template Author&#39;s Guide</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_misc.html"><span itemprop="name">Miscellaneous</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="dgui_misc_autoescaping.html"><span itemprop="name">Auto-escaping and output formats</span></a></li></ul> </div>
<div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul><li><a href="alphaidx.html">Alpha. index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions</a></li><li><a href="ref_builtins_alphaidx.html">?builtins</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_specvar.html">.spec_vars</a></li><li><a href="app_faq.html">FAQ</a></li></ul></div></div></div> <div class="main-content site-width">
<div class="content-wrapper">
<div id="table-of-contents-wrapper" class="col-left">
<script>var breadcrumb = ["Apache FreeMarker Manual","Template Author\'s Guide","Miscellaneous","Auto-escaping and output formats"];</script>
<script src="toc.js?1707770044859"></script>
<script src="docgen-resources/main.min.js?1707770044859"></script>
</div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="dgui_misc_namespace.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_computer_vs_human_format.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="dgui_misc_autoescaping" itemprop="headline">Auto-escaping and output formats</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#dgui_misc_autoescaping_outputformat" data-menu-target="dgui_misc_autoescaping_outputformat">Output formats</a></li><li><a class="page-menu-link" href="#dgui_misc_autoescaping_overrideoformat" data-menu-target="dgui_misc_autoescaping_overrideoformat">Overriding the output format in templates</a></li><li><a class="page-menu-link" href="#dgui_misc_autoescaping_disableautoesc" data-menu-target="dgui_misc_autoescaping_disableautoesc">Disabling auto escaping</a></li><li><a class="page-menu-link" href="#dgui_misc_autoescaping_movalues" data-menu-target="dgui_misc_autoescaping_movalues">"Markup output" values</a></li><li><a class="page-menu-link" href="#autoid_28" data-menu-target="autoid_28">Further details and tricky cases</a><ul><li><a class="page-menu-link" href="#dgui_misc_autoescaping_nonmarkupof" data-menu-target="dgui_misc_autoescaping_nonmarkupof">Non-markup output formats</a></li><li><a class="page-menu-link" href="#dgui_misc_autoescaping_mixingoutputformats" data-menu-target="dgui_misc_autoescaping_mixingoutputformats">Inserting markup output values from other markups</a></li><li><a class="page-menu-link" href="#dgui_misc_autoescaping_concatenation" data-menu-target="dgui_misc_autoescaping_concatenation">Markup output values and the "+"
operator</a></li><li><a class="page-menu-link" href="#dgui_misc_autoescaping_stringliteral" data-menu-target="dgui_misc_autoescaping_stringliteral">${...} inside string literals</a></li><li><a class="page-menu-link" href="#autoid_29" data-menu-target="autoid_29">Combined output formats</a></li></ul></li></ul> </div><p>This is a <em>detailed</em> tutorial to
auto-escaping and related concepts; for the bare minimum, <a href="dgui_quickstart_template.html#dgui_quickstart_template_autoescaping">read this
instead</a>.</p> <div class="callout note">
<strong class="callout-label">Note:</strong>
<p>The kind of automatic escaping described here requires at
least FreeMarker 2.3.24. If you have to use an earlier version, use
the deprecated <a href="ref_directive_escape.html"><code>escape</code>
directive</a> instead.</p>
</div>
<h2 class="content-header header-section2" id="dgui_misc_autoescaping_outputformat">Output formats</h2>
<p>Each template has an associated output format <span class="marked-for-programmers">(a
<code class="inline-code">freemarker.core.OutputFormat</code> instance)</span>.
The output format dictates the escaping rules, which is applied on
all <code class="inline-code">${<em class="code-color">...</em>}</code>-s (and
<code class="inline-code">#{<em class="code-color">...</em>}</code>-s) that aren&#39;t
<a href="#dgui_misc_autoescaping_stringliteral">inside a string
literal</a>. It also specifies a MIME type (e.g.
<code class="inline-code">&quot;text/HTML&quot;</code>) and a canonical name (e.g.
<code class="inline-code">&quot;HTML&quot;</code>) that the embedding application/framework
can use for its own purposes.</p>
<p>It&#39;s the programmer&#39;s responsibility to <a href="pgui_config_outputformatsautoesc.html">associate output format
to templates</a>. Furthermore it&#39;s recommended that FreeMarker is
configured so that templates with <code class="inline-code">ftlh</code> and
<code class="inline-code">ftlx</code> file extensions are automatically associated
with the HTML and XML output formats, respectively.</p>
<p><a name="topic.predefinedOutputFormats"></a>The predefined output
formats are:</p>
<div class="table-responsive">
<table class="table">
<thead>
<tr>
<th>Name</th>
<th>Description</th>
<th>MIME Type</th>
<th>Default implementation
(<code class="inline-code">freemarker.core.*</code>)</th>
</tr>
</thead>
<tbody>
<tr>
<td><code class="inline-code">HTML</code></td>
<td>Escapes <code class="inline-code">&lt;</code>, <code class="inline-code">&gt;</code>,
<code class="inline-code">&amp;</code>, <code class="inline-code">&quot;</code>,
<code class="inline-code">&#39;</code> as <code class="inline-code">&amp;lt;</code>,
<code class="inline-code">&amp;gt;</code>, <code class="inline-code">&amp;amp;</code>,
<code class="inline-code">&amp;quot;</code>,
<code class="inline-code">&amp;#39;</code></td>
<td><code class="inline-code">text/html</code></td>
<td><code class="inline-code">HTMLOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">XHTML</code></td>
<td>Escapes <code class="inline-code">&lt;</code>, <code class="inline-code">&gt;</code>,
<code class="inline-code">&amp;</code>, <code class="inline-code">&quot;</code>,
<code class="inline-code">&#39;</code> as <code class="inline-code">&amp;lt;</code>,
<code class="inline-code">&amp;gt;</code>, <code class="inline-code">&amp;amp;</code>,
<code class="inline-code">&amp;quot;</code>,
<code class="inline-code">&amp;#39;</code></td>
<td><code class="inline-code">application/xhtml+xml</code></td>
<td><code class="inline-code">XHTMLOutputFormat.INSTANCE</code></td>
</tr>
</tbody>
<tbody>
<tr>
<td><code class="inline-code">XML</code></td>
<td>Escapes <code class="inline-code">&lt;</code>, <code class="inline-code">&gt;</code>,
<code class="inline-code">&amp;</code>, <code class="inline-code">&quot;</code>,
<code class="inline-code">&#39;</code> as <code class="inline-code">&amp;lt;</code>,
<code class="inline-code">&amp;gt;</code>, <code class="inline-code">&amp;amp;</code>,
<code class="inline-code">&amp;quot;</code>,
<code class="inline-code">&amp;apos;</code></td>
<td><code class="inline-code">application/xml</code></td>
<td><code class="inline-code">XMLOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">RTF</code></td>
<td>Escapes <code class="inline-code">{</code>, <code class="inline-code">}</code>,
<code class="inline-code">\</code> as <code class="inline-code">\{</code>,
<code class="inline-code">\}</code>, <code class="inline-code">\\</code></td>
<td><code class="inline-code">application/rtf</code></td>
<td><code class="inline-code">RTFOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">undefined</code></td>
<td>Doesn&#39;t escape. Prints markup output values (concept
explained <a href="#dgui_misc_autoescaping_movalues">later</a>) from
other output formats as is. The default output format used
when no output format was explicitly set in the
configuration.</td>
<td>None (<code class="inline-code">null</code>)</td>
<td><code class="inline-code">UndefinedOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">plainText</code></td>
<td>Doesn&#39;t escape.</td>
<td><code class="inline-code">text/plain</code></td>
<td><code class="inline-code">PlainTextOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">JavaScript</code></td>
<td>Doesn&#39;t escape.</td>
<td><code class="inline-code">application/javascript</code></td>
<td><code class="inline-code">JavaScriptOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">JSON</code></td>
<td>Doesn&#39;t escape.</td>
<td><code class="inline-code">application/json</code></td>
<td><code class="inline-code">JSONOutputFormat.INSTANCE</code></td>
</tr>
<tr>
<td><code class="inline-code">CSS</code></td>
<td>Doesn&#39;t escape.</td>
<td><code class="inline-code">text/css</code></td>
<td><code class="inline-code">CSSOutputFormat.INSTANCE</code></td>
</tr>
</tbody>
</table>
</div>
<p>The programmers can add their your own output formats, so this
is maybe not all the output formats in your application!</p>
<h2 class="content-header header-section2" id="dgui_misc_autoescaping_overrideoformat">Overriding the output format in templates</h2>
<p>Especially in legacy applications, you will often find that
the output format is <code class="inline-code">undefined</code> (you can check
that with <code class="inline-code">${.output_format}</code>), and so no automatic
escaping is happening. In other cases, a common output format (like
HTML) is set for all templates, but a few templates need a different
output format. In any case, the output format of a template can be
enforced in the <a href="ref_directive_ftl.html">the
<code>ftl</code> header</a>:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#ftl output_format=&quot;XML&quot;&gt;
${&quot;&#39;&quot;} &lt;#-- Prints: &amp;apos; --&gt;</pre> </div>
<p>Above, the output format was referred by its name shown in the
earlier table <em>(looked up via
<code class="inline-code">Configuration.getOutputFormat(String name)</code>,
actually)</em>.</p>
<div class="callout note">
<strong class="callout-label">Note:</strong>
<p>If escaping doesn&#39;t happen after adding the above
<code class="inline-code">ftl</code> header, then <code class="inline-code">&lt;#ftl
output_format=&quot;XML&quot; auto_esc=true&gt;</code> might helps (and
that means that FreeMarker was configured to use
"disable" auto-escaping <em>policy</em>,
which is generally not recommended).</p>
</div>
<p>The output format can also be applied to only a section of a
template, like:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- Let&#39;s assume we have &quot;HTML&quot; output format by default. --&gt;
${&quot;&#39;&quot;} &lt;#-- Prints: &amp;#39; --&gt;
&lt;#outputformat &quot;XML&quot;&gt;
${&quot;&#39;&quot;} &lt;#-- Prints: &amp;apos; --&gt;
&lt;/#outputformat&gt;
${&quot;&#39;&quot;} &lt;#-- Prints: &amp;#39; --&gt;</pre> </div>
<p>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&#39;t change as the template executes. So if, for example, you
call a macro from inside an <code class="inline-code">outputformat</code> block
and the called macro is defined outside that block, it won&#39;t get the
output format of it. Or, if you have a macro that&#39;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&#39;t have to consider the possible execution
paths that can lead to a point.</p>
<h2 class="content-header header-section2" id="dgui_misc_autoescaping_disableautoesc">Disabling auto escaping</h2>
<p>For a single interpolation you can disable auto-escaping with
<a href="ref_builtins_string.html#ref_builtin_no_esc"><code>?no_esc</code></a>:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- Let&#39;s assume we have &quot;HTML&quot; output format by default. --&gt;
${&#39;&lt;b&gt;test&lt;/b&gt;&#39;} &lt;#-- prints: &amp;lt;b&amp;gt;test&amp;lt;/b&amp;gt; --&gt;
${&#39;&lt;b&gt;test&lt;/b&gt;&#39;<strong>?no_esc</strong>} &lt;#-- prints: &lt;b&gt;test&lt;/b&gt; --&gt;</pre> </div>
<p>You can also disable auto escaping for a whole section with
the <a href="ref_directive_noautoesc.html"><code>noautoesc</code>
directive</a>:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">${&#39;&amp;&#39;} &lt;#-- prints: &amp;amp; --&gt;
<strong>&lt;#noautoesc&gt;</strong>
${&#39;&amp;&#39;} &lt;#-- prints: &amp; --&gt;
...
${&#39;&amp;&#39;} &lt;#-- prints: &amp; --&gt;
<strong>&lt;/#noautoesc&gt;</strong>
${&#39;&amp;&#39;} &lt;#-- prints: &amp;amp; --&gt;</pre> </div>
<p>Just like <code class="inline-code">outputformat</code>, this only applies
to the part that&#39;s literally inside the block
("coloring" logic).</p>
<p>Auto-escaping can also be disabled for the whole template in
the <code class="inline-code">ftl</code> header. It can then be re-enabled for a
section with the <a href="ref_directive_autoesc.html"><code>autoesc</code>
directive</a>:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#ftl <strong>autoesc=false</strong>&gt;
${&#39;&amp;&#39;} &lt;#-- prints: &amp; --&gt;
<strong>&lt;#autoesc&gt;</strong>
${&#39;&amp;&#39;} &lt;#-- prints: &amp;amp; --&gt;
...
${&#39;&amp;&#39;} &lt;#-- prints: &amp;amp; --&gt;
<strong>&lt;/#autoesc&gt;</strong>
${&#39;&amp;&#39;} &lt;#-- prints: &amp; --&gt;</pre> </div>
<p>You can also force escaping for an individual interpolation
when escaping is disabled, with <a href="ref_builtins_string.html#ref_builtin_esc"><code>?esc</code></a>:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#ftl <strong>autoesc=false</strong>&gt;
${&#39;&amp;&#39;} &lt;#-- prints: &amp; --&gt;
${&#39;&amp;&#39;<strong>?esc</strong>} &lt;#-- prints: &amp;amp; --&gt;</pre> </div>
<p>Naturally, both <code class="inline-code">autoesc</code> and
<code class="inline-code">?esc</code> works inside <code class="inline-code">noautoesc</code>
blocks too.</p>
<h2 class="content-header header-section2" id="dgui_misc_autoescaping_movalues">"Markup output" values</h2>
<p>In FTL, <a href="dgui_datamodel_basics.html">values have
type</a>, like string, number, boolean, etc. One such type is
called "markup output". A value of that type is a piece
of text that&#39;s already in the output format (like HTML), and hence
needs no further escaping. We have already produced such values
earlier:</p>
<ul>
<li>
<p><code class="inline-code"><em class="code-color">s</em>?esc</code>
creates a markup output value out of a string value by escaping
all special characters in it.</p>
</li>
<li>
<p><code class="inline-code"><em class="code-color">s</em>?no_esc</code>
creates a markup output value out of a string value by assuming
that the string already stores markup and so needs no further
escaping</p>
</li>
</ul>
<p>These can be useful outside
<code class="inline-code">${<em class="code-color">...</em>}</code> too. For
example, here the caller of the <code class="inline-code">infoBox</code> macro can
decide if the message is plain text (hence needs escaping) or HTML
(hence it mustn&#39;t be escaped):</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;HTML&quot; output format by default. --&gt;
&lt;@infoBox &quot;Foo &amp; bar&quot; /&gt;
&lt;@infoBox &quot;Foo &lt;b&gt;bar&lt;/b&gt;&quot;?no_esc /&gt;
&lt;#macro infoBox message&gt;
&lt;div class=&quot;infoBox&quot;&gt;
${message}
&lt;/div&gt;
&lt;/#macro&gt;</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body"> &lt;div class=&quot;infoBox&quot;&gt;
Foo &amp;amp; bar
&lt;/div&gt;
&lt;div class=&quot;infoBox&quot;&gt;
Foo &lt;b&gt;bar&lt;/b&gt;
&lt;/div&gt;</pre> </div>
<p>Another case where you get a markup output value is output
capturing:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;HTML&quot; output format by default. --&gt;
&lt;#assign captured&gt;&lt;b&gt;Test&lt;/b&gt;&lt;/#assign&gt;
Just a string: ${&quot;&lt;b&gt;Test&lt;/b&gt;&quot;}
Captured output: ${captured}</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">Just a string: &amp;lt;b&amp;gt;Test&amp;lt;/b&amp;gt;
Captured output: &lt;b&gt;Test&lt;/b&gt;</pre> </div>
<p>Because the captured output is markup output, it wasn&#39;t
auto-escaped.</p>
<p>It&#39;s important that markup output values aren&#39;t strings, and
aren&#39;t automatically coerced to strings. Thus
<code class="inline-code">?upper_case</code>, <code class="inline-code">?starts_with</code>
etc., will give an error with them. You won&#39;t be able to pass them
to Java methods for <code class="inline-code">String</code> parameters either. But
sometimes you need the markup that&#39;s behind the value as a string,
which you can get as
<code class="inline-code"><em class="code-color">markupOutput</em>?markup_string</code>.
Be sure you know what you are doing though. Applying string
operations on markup (as opposed to on plain text) can result in
invalid markup. Also there&#39;s the danger of unintended double
escaping.</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;HTML&quot; output format by default. --&gt;
&lt;#assign markupOutput1=&quot;&lt;b&gt;Test&lt;/b&gt;&quot;?no_esc&gt;
&lt;#assign markupOutput2=&quot;Foo &amp; bar&quot;?esc&gt;
As expected:
${markupOutput1}
${markupOutput2}
Possibly unintended double escaping:
${markupOutput1?markup_string}
${markupOutput2?markup_string}</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">As expected:
&lt;b&gt;Test&lt;/b&gt;
Foo &amp;amp; bar
Possibly unintended double escaping:
&amp;lt;b&amp;gt;Test&amp;lt;/b&amp;gt;
Foo &amp;amp;amp; bar</pre> </div>
<h2 class="content-header header-section2" id="autoid_28">Further details and tricky cases</h2>
<h3 class="content-header header-section3" id="dgui_misc_autoescaping_nonmarkupof">Non-markup output formats</h3>
<p>An output format is said to be a non-markup format if it
defines no escaping rules. Examples of such output formats are the
<code class="inline-code">undefined</code> format and the
<code class="inline-code">plainText</code> format.</p>
<p>These formats produce no <a href="#dgui_misc_autoescaping_movalues">markup output
values</a>, hence you can&#39;t use <code class="inline-code">?esc</code> or
<code class="inline-code">?no_esc</code> when they are the current format. You
can use output capturing (like <code class="inline-code">&lt;#assign
captured&gt;<em class="code-color">...</em>&lt;/#assign&gt;</code>),
but the resulting value will be a string, not a markup output
value.</p>
<p>Furthermore, you aren&#39;t allowed to use the
<code class="inline-code">autoesc</code> directive or <code class="inline-code">&lt;#ftl
auto_esc=true&gt;</code> when the current output format is
non-markup.</p>
<p>Using constructs that aren&#39;t supported by the current output
format will give <a href="gloss.html#gloss.parseTimeError">parse-time
error</a>.</p>
<h3 class="content-header header-section3" id="dgui_misc_autoescaping_mixingoutputformats">Inserting markup output values from other markups</h3>
<p>Each <a href="#dgui_misc_autoescaping_movalues">markup
output value</a> has an associated <a href="#dgui_misc_autoescaping_outputformat">output
format</a>. When a markup output value is inserted with
<code class="inline-code">${<em class="code-color">...</em>}</code> (or
<code class="inline-code">#{<em class="code-color">...</em>}</code>), it has to
be converted to the current output format at the point of
insertion (if they differ). As of this writing (2.3.24), such
output format conversion will only be successful if the value to
convert was created by escaping plain text:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;HTML&quot; output format by default. --&gt;
&lt;#assign mo1 = &quot;Foo&#39;s bar {}&quot;?esc&gt;
HTML: ${mo1}
XML: &lt;#outputformat &#39;XML&#39;&gt;${mo1}&lt;/#outputformat&gt;
RTF: &lt;#outputformat &#39;RTF&#39;&gt;${mo1}&lt;/#outputformat&gt;
&lt;#assign mo2&gt;&lt;p&gt;Test&lt;/#assign&gt;
HTML: ${mo2}
XML: &lt;#attempt&gt;&lt;#outputformat &#39;XML&#39;&gt;${mo2}&lt;/#outputformat&gt;&lt;#recover&gt;Failed&lt;/#attempt&gt;
RTF: &lt;#attempt&gt;&lt;#outputformat &#39;RTF&#39;&gt;${mo2}&lt;/#outputformat&gt;&lt;#recover&gt;Failed&lt;/#attempt&gt;</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">HTML: Foo&amp;#39;s bar {}
XML: Foo&amp;apos;s bar {}
RTF: Foo&#39;s bar \{\}
HTML: &lt;p&gt;Test
XML: Failed
RTF: Failed</pre> </div>
<p>But, an output format can also chose to insert pieces of
other output formats as is, without converting them. Among the
standard output formats, <code class="inline-code">undefined</code> is like
that, which is the output format used for templates for which no
output format was specified in the configuration:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;undefined&quot; output format here. --&gt;
&lt;#outputformat &quot;HTML&quot;&gt;&lt;#assign htmlMO&gt;&lt;p&gt;Test&lt;/#assign&gt;&lt;/#outputformat&gt;
&lt;#outputformat &quot;XML&quot;&gt;&lt;#assign xmlMO&gt;&lt;p&gt;Test&lt;/p&gt;&lt;/#assign&gt;&lt;/#outputformat&gt;
&lt;#outputformat &quot;RTF&quot;&gt;&lt;#assign rtfMO&gt;\par Test&lt;/#assign&gt;&lt;/#outputformat&gt;
HTML: ${htmlMO}
XML: ${xmlMO}
RTF: ${rtfMO}</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">HTML: &lt;p&gt;Test
XML: &lt;p&gt;Test&lt;/p&gt;
RTF: \par Test</pre> </div>
<h3 class="content-header header-section3" id="dgui_misc_autoescaping_concatenation">Markup output values and the "+"
operator</h3>
<p>As you certainly know, if one of the sides of the
<code class="inline-code">+</code> operator is a string then <a href="dgui_template_exp.html#dgui_template_exp_stringop_concatenation">it does
concatenation</a>. If there&#39;s a <a href="#dgui_misc_autoescaping_movalues">markup output
value</a> in one side, the other side gets promoted to markup
output value of the same output format (if it&#39;s not already that),
by escaping its string value, and finally the two markups are
concatenated to form a new markup output value. Example:</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;HTML&quot; output format by default. --&gt;
${&quot;&lt;h1&gt;&quot;?no_esc + &quot;Foo &amp; bar&quot; + &quot;&lt;/h1&gt;&quot;?no_esc}</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">&lt;h1&gt;Foo &amp;amp; bar&lt;/h1&gt;</pre> </div>
<p>If the two sides of the <code class="inline-code">+</code> operator are
markup values of different output formats, the right side operand
is converted to the output format of the left side. If that&#39;s not
possible, then the left side operand is converted to the output
format of the right side. If that isn&#39;t possible either, that&#39;s an
error. (See the <a href="#dgui_misc_autoescaping_mixingoutputformats">limitations
of conversions here</a>.)</p>
<h3 class="content-header header-section3" id="dgui_misc_autoescaping_stringliteral">${...} inside string literals</h3>
<p>When <code class="inline-code">${<em class="code-color">...</em>}</code> is
used inside string <em>expressions</em> (e.g., in
<code class="inline-code">&lt;#assign s = &quot;Hello ${name}!&quot;&gt;</code>), it&#39;s
just a shorthand of using the <code class="inline-code">+</code> operator
(<code class="inline-code">&lt;#assign s = &quot;Hello&quot; + name + &quot;!&quot;&gt;</code>).
Thus, <code class="inline-code">${<em class="code-color">...</em>}</code>-s
inside string expressions aren&#39;t auto-escaped, but of course when
the resulting concatenated string is printed later, it will be
possibly auto-escaped.</p>
<div class="code-block role-template">
<div class="code-block-label">Template</div><pre class="code-block-body">&lt;#-- We assume that we have &quot;HTML&quot; output format by default. --&gt;
&lt;#assign name = &quot;Foo &amp; Bar&quot;&gt;
&lt;#assign s = &quot;&lt;p&gt;Hello ${name}!&quot;&gt;
${s}
&lt;p&gt;Hello ${name}!
To prove that s didn&#39;t contain the value in escaped form:
${s?replace(&#39;&amp;&#39;), &#39;and&#39;}</pre> </div>
<div class="code-block role-output">
<div class="code-block-label">Output</div><pre class="code-block-body">&amp;lt;p&amp;gt;Hello Foo &amp;amp; Bar!
&lt;p&gt;Hello Foo &amp;amp; Bar!
To prove that &quot;s&quot; didn&#39;t contain the value in escaped form:
&amp;lt;p&amp;gt;Hello Foo and Bar!</pre> </div>
<h3 class="content-header header-section3" id="autoid_29">Combined output formats</h3>
<p>Combined output formats are output formats that are created
ad-hoc from other output formats by nesting them into each other,
so that the escaping of both output formats are applied. <a href="ref_directive_outputformat.html#topic.combinedOutputFormats">They are discussed
here...</a></p>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="dgui_misc_namespace.html"><span>Previous</span></a><a class="paging-arrow next" href="dgui_misc_computer_vs_human_format.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-top"><div class="col-left sitemap"><div class="column"><h3 class="column-header">Overview</h3><ul><li><a href="https://freemarker.apache.org/">What is FreeMarker?</a></li><li><a href="https://freemarker.apache.org/freemarkerdownload.html">Download</a></li><li><a href="app_versions.html">Version history</a></li><li><a href="app_faq.html">FAQ</a></li><li><a itemprop="license" href="app_license.html">License</a></li><li><a href="https://privacy.apache.org/policies/privacy-policy-public.html">Privacy policy</a></li></ul></div><div class="column"><h3 class="column-header">Often used / Reference</h3><ul><li><a href="https://try.freemarker.apache.org/">Try template online</a></li><li><a href="dgui_template_exp.html#exp_cheatsheet">Expressions cheatsheet</a></li><li><a href="ref_directive_alphaidx.html">#directives</a></li><li><a href="ref_builtins_alphaidx.html">?built_ins</a></li><li><a href="ref_specvar.html">.special_vars</a></li><li><a href="api/freemarker/core/Configurable.html#setSetting-java.lang.String-java.lang.String-">Configuration settings</a></li></ul></div><div class="column"><h3 class="column-header">Community</h3><ul><li><a href="https://github.com/apache/freemarker">Github project page</a></li><li><a href="https://issues.apache.org/jira/projects/FREEMARKER">Report a bug</a></li><li><a href="https://freemarker.apache.org/report-security-vulnerabilities.html">Report security vulnerability</a></li><li><a href="https://stackoverflow.com/questions/ask?tags=freemarker">Get help on StackOverflow</a></li><li><a href="https://twitter.com/freemarker">Announcements on Twitter</a></li><li><a href="https://freemarker.apache.org/mailing-lists.html">Discuss on mailing lists</a></li></ul></div></div><div class="col-right"><ul class="social-icons"><li><a class="github" href="https://github.com/apache/freemarker">Github</a></li><li><a class="twitter" href="https://twitter.com/freemarker">Twitter</a></li><li><a class="stack-overflow" href="https://stackoverflow.com/questions/ask?tags=freemarker">Stack Overflow</a></li></ul><a class="xxe" href="http://www.xmlmind.com/xmleditor/" rel="nofollow" title="Edited with XMLMind XML Editor"><span>Edited with XMLMind XML Editor</span></a></div></div><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2024-02-12T20:34:04Z" title="Monday, February 12, 2024 at 8:34:04 PM Greenwich Mean Time">2024-02-12 20:34:04 GMT</time>, for Freemarker 2.3.32 </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2024
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a>. Apache FreeMarker, FreeMarker, Apache Incubator, Apache, the Apache FreeMarker logo are trademarks of The Apache Software Foundation. All other marks mentioned may be trademarks or registered trademarks of their respective owners. </p>
</div></div></div></body>
</html>