blob: fe71e236aa4e9067b769bffd288939bd4c3c6eb2 [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>escape, noescape - 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="FreeMarker Manual">
<meta property="og:title" content="escape, noescape">
<meta property="og:locale" content="en_US">
<meta property="og:url" content="http://example.com/ref_directive_escape.html">
<link rel="canonical" href="http://example.com/ref_directive_escape.html">
<link rel="icon" href="favicon.png" type="image/png">
<link rel="stylesheet" type="text/css" href="docgen-resources/docgen.min.css?1594338517553">
</head>
<body itemscope itemtype="https://schema.org/Code">
<meta itemprop="url" content="http://example.com/">
<meta itemprop="name" content="FreeMarker Manual">
<!--[if lte IE 9]>
<div style="background-color: #C00; color: #fff; padding: 12px 24px;">Please use a modern browser to view this website.</div>
<![endif]--><div class="header-top-bg"><div class="site-width header-top"><a class="logo" href="http://example.com" role="banner"> <img itemprop="image" src="logo.png" alt="My Logo">
</a></div></div><div class="header-bottom-bg"><div class="site-width search-row"><a href="index.html" class="navigation-header">FreeMarker Manual</a><div class="navigation-header"></div></div><div class="site-width breadcrumb-row"><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">FreeMarker Manual</span></a></li><li class="step-1" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="ref.html"><span itemprop="name">Reference</span></a></li><li class="step-2" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="ref_directives.html"><span itemprop="name">Directive Reference</span></a></li><li class="step-3" itemprop="itemListElement" itemscope itemtype="http://schema.org/ListItem"><a class="label" itemprop="item" href="ref_directive_escape.html"><span itemprop="name">escape, noescape</span></a></li></ul><div class="bookmarks" title="Bookmarks"><span class="sr-only">Bookmarks:</span><ul class="bookmark-list"><li><a href="alphaidx.html">Index</a></li><li><a href="gloss.html">Glossary</a></li><li><a href="ref.html">Reference</a></li><li><a href="app_faq.html">FAQ</a></li><li><a href="preface.html#test_target">Bőregér</a></li></ul></div></div></div> <div class="main-content site-width">
<div class="content-wrapper no-toc">
<div id="table-of-contents-wrapper" class="col-left">
</div>
<div class="col-right"><div class="page-content"><div class="page-title"><div class="pagers top"><a class="paging-arrow previous" href="ref_directive_compress.html"><span>Previous</span></a><a class="paging-arrow next" href="ref_directive_assign.html"><span>Next</span></a></div><div class="title-wrapper">
<h1 class="content-header header-section1" id="ref_directive_escape" itemprop="headline">escape, noescape</h1>
</div></div><div class="page-menu">
<div class="page-menu-title">Page Contents</div>
<ul><li><a class="page-menu-link" href="#autoid_92" data-menu-target="autoid_92">Synopsis</a></li><li><a class="page-menu-link" href="#autoid_93" data-menu-target="autoid_93">Description</a></li></ul> </div><a name="ref.directive.escape"></a><a name="ref.directive.noescape"></a>
<h2 class="content-header header-section2" id="autoid_92">Synopsis</h2>
<pre class="metaTemplate">
<code class="inline-code">&lt;#escape <em class="code-color">identifier</em> as <em class="code-color">expression</em>&gt;
<em class="code-color">...</em>
&lt;#noescape&gt;...&lt;/#noescape&gt;
<em class="code-color">...</em>
&lt;/#escape&gt;</code>
</pre>
<h2 class="content-header header-section2" id="autoid_93">Description</h2>
<p>When you surround a part of the template with an escape
directive, interpolations
(<code class="inline-code">${<em class="code-color">...</em>}</code>) that occur
inside the block are combined with the escaping expression
automatically. This is a convenience method for avoiding writing
similar expressions all over. It does not affect interpolations in
string literals (as in <code class="inline-code">&lt;#assign x =
&quot;Hello ${user}!&quot;&gt;</code>). Also, it does not affect numerical
interpolations
(<code class="inline-code">#{<em class="code-color">...</em>}</code>).</p>
<p>Example:</p>
<div class="code-wrapper"><pre class="code-block code-template"><strong>&lt;#escape x as x?html&gt;</strong>
First name: ${firstName}
Last name: ${lastName}
Maiden name: ${maidenName}
<strong>&lt;/#escape&gt;</strong></pre></div>
<p>is actually equivalent to:</p>
<div class="code-wrapper"><pre class="code-block code-template"> First name: ${firstName<strong>?html</strong>}
Last name: ${lastName<strong>?html</strong>}
Maiden name: ${maidenName<strong>?html</strong>}</pre></div>
<p>Note that it is irrelevant what identifier you use in the
directive - it just serves as a formal parameter to the escaping
expression.</p>
<p>When you are calling macros or the <code class="inline-code">include</code>
directive, it is important to understand that escape has effect only
on interpolations that occur between the <code class="inline-code">&lt;#escape
<em class="code-color">...</em>&gt;</code> and
<code class="inline-code">&lt;/#escape&gt;</code> <em>in the template
text</em>. That is, it will not escape anything that is before
<code class="inline-code">&lt;#escape <em class="code-color">...</em>&gt;</code> in
the text, or after the <code class="inline-code">&lt;/#escape&gt;</code> in the
text, not even if that part is called from inside the
<code class="inline-code">escape</code>-d section.</p>
<div class="code-wrapper"><pre class="code-block code-template">&lt;#assign x = &quot;&lt;test&gt;&quot;&gt;
&lt;#macro m1&gt;
m1: ${x}
&lt;/#macro&gt;
&lt;#escape x as x?html&gt;
&lt;#macro m2&gt;m2: ${x}&lt;/#macro&gt;
${x}
&lt;@m1/&gt;
&lt;/#escape&gt;
${x}
&lt;@m2/&gt;</pre></div>
<p>the output will be:</p>
<div class="code-wrapper"><pre class="code-block code-output"> &amp;lt;test&amp;gt;
m1: &lt;test&gt;
&lt;test&gt;
m2: &amp;lt;test&amp;gt;</pre></div>
<p><span class="marked-for-programmers">More technically, the effects of
<code class="inline-code">escape</code> directive are applied at template parsing
time rather than at template processing time. This means that if you
call a macro or include another template from within an escape
block, it won&#39;t affect the interpolations in the macro/included
template, since macro calls and template includes are evaluated at
template processing time. On the other hand, if you surround one or
more macro declarations (which are evaluated at template parsing
time, as opposed to macro calls) with an escape block, the
interpolations in those macros will be combined with the escaping
expression.</span></p>
<p>Sometimes there is a need to temporarily turn off escaping for
one or two interpolations in an escape block. You can achieve this
by closing and later reopening the escape block, but then you have
to write the escaping expression twice. You can instead use the
noescape directive:</p>
<div class="code-wrapper"><pre class="code-block code-template">&lt;#escape x as x?html&gt;
From: ${mailMessage.From}
Subject: ${mailMessage.Subject}
<strong>&lt;#noescape&gt;</strong>Message: ${mailMessage.htmlFormattedBody}<strong>&lt;/#noescape&gt;</strong>
<em>...</em>
&lt;/#escape&gt;</pre></div>
<p>is equivalent to:</p>
<div class="code-wrapper"><pre class="code-block code-template"> From: ${mailMessage.From?html}
Subject: ${mailMessage.Subject?html}
Message: ${mailMessage.htmlFormattedBody}
...</pre></div>
<p>Escapes can be nested (although you will do it only in rare
circumstances). Therefore, you can write something like the below
code (the example is admittedly a bit stretched, as you&#39;d probably
place item codes in a sequence and use <code class="inline-code">list</code> to
iterate over them, but we&#39;re now doing it this way just to
illustrate the point):</p>
<div class="code-wrapper"><pre class="code-block code-template"><strong>&lt;#escape x as x?html&gt;</strong>
Customer Name: ${customerName}
Items to ship:
<strong>&lt;#escape x as itemCodeToNameMap[x]&gt;</strong>
${itemCode1}
${itemCode2}
${itemCode3}
${itemCode4}
<strong>&lt;/#escape&gt;</strong>
<strong>&lt;/#escape&gt;</strong></pre></div>
<p>is actually equivalent to:</p>
<div class="code-wrapper"><pre class="code-block code-template"> Customer Name: ${customerName?html}
Items to ship:
${itemCodeToNameMap[itemCode1]?html}
${itemCodeToNameMap[itemCode2]?html}
${itemCodeToNameMap[itemCode3]?html}
${itemCodeToNameMap[itemCode4]?html}</pre></div>
<p>When you use the noescape directive in a nested escape block,
it undoes only a single level of escaping. Therefore, to completely
turn off escaping in a two-level deep escaped block, you need to use
two nested noescape directives as well.</p>
<div class="bottom-pagers-wrapper"><div class="pagers bottom"><a class="paging-arrow previous" href="ref_directive_compress.html"><span>Previous</span></a><a class="paging-arrow next" href="ref_directive_assign.html"><span>Next</span></a></div></div></div></div> </div>
</div>
<div class="site-footer"><div class="site-width"><div class="footer-bottom"> <p class="last-generated">
Last generated:
<time itemprop="dateModified" datetime="2020-07-09T23:48:37Z" title="Thursday, July 9, 2020 11:48:37 PM GMT">2020-07-09 23:48:37 GMT</time> </p>
<p class="copyright">
© <span itemprop="copyrightYear">1999</span>–2020
<a itemtype="http://schema.org/Organization" itemprop="copyrightHolder" href="https://apache.org/">The Apache Software Foundation</a> </p>
</div></div></div></body>
</html>