Author: cbrisson
Date: Mon Oct 15 16:21:07 2018
New Revision: 1843925
URL: http://svn.apache.org/viewvc?rev=1843925&view=rev
Log:
[site] Document last changes; and nicifies/fixes things here and there (=> prod)
Modified:
velocity/site/production/css/site.css
velocity/site/production/engine/devel/changes.html
velocity/site/production/engine/devel/configuration.html
velocity/site/production/engine/devel/upgrading.html
velocity/site/production/engine/devel/user-guide.html
velocity/site/production/engine/devel/vtl-reference.html
Modified: velocity/site/production/css/site.css
URL:
http://svn.apache.org/viewvc/velocity/site/production/css/site.css?rev=1843925&r1=1843924&r2=1843925&view=diff
==============================================================================
--- velocity/site/production/css/site.css (original)
+++ velocity/site/production/css/site.css Mon Oct 15 16:21:07 2018
@@ -453,6 +453,16 @@ table.conversions th
word-wrap: no;
}
+.blue
+{
+ color: blue;
+}
+
+.bigger
+{
+ font-size: bigger;
+}
+
/* Style adjustments for mobile devices */
@media screen and (max-width: 800px)
Modified: velocity/site/production/engine/devel/changes.html
URL:
http://svn.apache.org/viewvc/velocity/site/production/engine/devel/changes.html?rev=1843925&r1=1843924&r2=1843925&view=diff
==============================================================================
--- velocity/site/production/engine/devel/changes.html (original)
+++ velocity/site/production/engine/devel/changes.html Mon Oct 15 16:21:07 2018
@@ -322,6 +322,27 @@ h2:hover > .headerlink, h3:hover > .head
<td>
<img src="images/add.png"/>
</td>
+ <td> Added the <code> velocimacro.preserve.arguments.literals </code>
flag (false by default), for backward compatibility. When true, for any macro
argument that evaluates to null, the macro will display the provided argument
literal representation instead of the literal argument reference. . Fixes <a
href="https://issues.apache.org/jira/browse/VELOCITY-904">VELOCITY-904</a>.
</td>
+ <td>cbrisson</td>
+ </tr>
+ <tr>
+ <td>
+ <img src="images/add.png"/>
+ </td>
+ <td> Default block for empty loops: <code> #foreach($i in []) loop
block #else empty #end </code> . Fixes <a
href="https://issues.apache.org/jira/browse/VELOCITY-903">VELOCITY-903</a>.
</td>
+ <td>cbrisson</td>
+ </tr>
+ <tr>
+ <td>
+ <img src="images/fix.png"/>
+ </td>
+ <td> Include proper OSGi bundle informations in manifest files . Fixes
<a href="https://issues.apache.org/jira/browse/VELOCITY-888">VELOCITY-888</a>.
</td>
+ <td>cbrisson</td>
+ </tr>
+ <tr>
+ <td>
+ <img src="images/add.png"/>
+ </td>
<td> Alternate reference values: <code> ${foo|'foo'} </code> evaluates
to false whenever boolean evaluation of $foo is false . Fixes <a
href="https://issues.apache.org/jira/browse/VELOCITY-898">VELOCITY-898</a>.
</td>
<td>cbrisson</td>
</tr>
Modified: velocity/site/production/engine/devel/configuration.html
URL:
http://svn.apache.org/viewvc/velocity/site/production/engine/devel/configuration.html?rev=1843925&r1=1843924&r2=1843925&view=diff
==============================================================================
--- velocity/site/production/engine/devel/configuration.html (original)
+++ velocity/site/production/engine/devel/configuration.html Mon Oct 15
16:21:07 2018
@@ -250,7 +250,11 @@ h2:hover > .headerlink, h3:hover > .head
<li><a href="#context">Context</a></li>
<li><a href="#string-interning">String Interning</a></li>
<li><a href="#space-gobbling">Space Gobbling</a></li>
-<li><a href="#configuration-examples">Configuration Examples</a></li>
+<li><a href="#configuration-examples">Configuration Examples</a><ul>
+<li><a href="#resource-loading">Resource loading</a></li>
+<li><a href="#backward-compatibility">Backward compatibility</a></li>
+</ul>
+</li>
</ul>
</div>
<h2 id="configuring-velocity">Configuring Velocity<a class="headerlink"
href="#configuring-velocity" title="Permanent link">¶</a></h2>
@@ -429,6 +433,16 @@ h2:hover > .headerlink, h3:hover > .head
<blockquote>
<p>Defines name of the reference that can be used to get the body content (an
AST block) given for a block macro call (e.g. #@myMacro() has a body #end). The
default reference name is "bodyContent" (e.g. $bodyContent). This block macro
feature was introduced in Velocity 1.7.</p>
</blockquote>
+<p><strong><code>velocimacro.preserve.argument.literals =
false</code></strong></p>
+<blockquote>
+<p>Since 2.0, inside a macro, the rendering of null arguments uses the local
reference literal. For instance, the following VTL code</p>
+<div class="codehilite"><pre><span class="cp">#</span><span
class="nf">macro</span><span class="p">(</span> <span class="nf">display</span>
<span class="p">$</span><span class="nv">foo</span> <span
class="p">)</span><span class="x"> </span><span class="p">$</span><span
class="nv">foo</span><span class="x"> </span><span class="cp">#</span><span
class="nf">end</span><span class="x"></span>
+<span class="cp">#</span><span class="nf">display</span><span
class="p">(</span> <span class="p">$</span><span class="nv">null</span> <span
class="p">)</span><span class="x"></span>
+</pre></div>
+
+
+<p>will display <code>$foo</code>. To revert to the 1.x behavior, since 2.1,
you can set this property to true. The previous code will then display
<code>$null</code>.</p>
+</blockquote>
<p><strong><code>macro.provide.scope.control = false</code></strong></p>
<blockquote>
<p>Used to turn on the automatic provision of the $macro scope control during
#macro calls. The default is false. Set it to true if you need a local
namespace in macros or more advanced #break controls.</p>
@@ -467,7 +481,7 @@ h2:hover > .headerlink, h3:hover > .head
</blockquote>
<p><strong><code>parser.allows.dash.in.identifiers = false</code></strong></p>
<blockquote>
-<p>This is a backward compatibility option, false by default, which allows the
'<strong><code>-</code></strong>' character inside variable identifiers. If
enabled, be warned that you will have to surround the mathematical minus sign
with spaces for it to be correctly interpreted.</p>
+<p>This is a backward compatibility option, false by default, which allows the
'<strong><code>-</code></strong>' character inside variable identifiers
(available since 2.1). If enabled, be warned that you will have to surround the
mathematical minus sign with spaces for it to be correctly interpreted.</p>
</blockquote>
<h2 id="event-handlers">Event Handlers<a class="headerlink"
href="#event-handlers" title="Permanent link">¶</a></h2>
<p>See the <a href="developer-guide.html#event-handlers">Event Handlers</a>
section of the dev guide.</p>
@@ -523,6 +537,7 @@ h2:hover > .headerlink, h3:hover > .head
- <code>structured</code> : like previous, plus fix inner text blocks
indentation.</p>
</blockquote>
<h2 id="configuration-examples">Configuration Examples<a class="headerlink"
href="#configuration-examples" title="Permanent link">¶</a></h2>
+<h3 id="resource-loading">Resource loading<a class="headerlink"
href="#resource-loading" title="Permanent link">¶</a></h3>
<p>Configuring the resource loaders for Velocity is straightforward. The
properties that control the are listed in the <a
href="#Configuring_Resource_Loaders">resource configuration</a> section, for
further reference.</p>
<p>The first step in configuring one or more resource loaders is do 'declare'
them by name to Velocity. Use the property <code>resource.loader</code> and
list one or more loader names. You can use anything you want - these names are
used to associate configuration properties with a given loader.</p>
<div class="codehilite"><pre><span class="na">resource.loader</span> <span
class="o">=</span> <span class="s">file</span>
@@ -599,7 +614,24 @@ a resource loadercalled 'file', and are
<p>Node that the three names 'file', 'class', and 'jar' are merely for your
convenience and sanity. They can be anything you want - they are just used to
associate a set of properties together. However, it is recommended that you
use names that give some hint of the function.</p>
-<p>Note that while all three require very little configuration information for
proper operation, the ClasspathResourceLoader is the simplest.</p></div></div>
+<p>Note that while all three require very little configuration information for
proper operation, the ClasspathResourceLoader is the simplest.</p>
+<h3 id="backward-compatibility">Backward compatibility<a class="headerlink"
href="#backward-compatibility" title="Permanent link">¶</a></h3>
+<p>The following configuration maximizes the backward compatibility with
Velocity 1.7.</p>
+<div class="codehilite"><pre><span class="c"># No automatic conversion of
methods arguments</span>
+<span class="na">runtime.conversion.handler</span> <span class="o">=</span>
<span class="s">none</span>
+
+<span class="c"># Use backward compatible space gobbling</span>
+<span class="na">space.gobbling</span> <span class="o">=</span> <span
class="s">bc</span>
+
+<span class="c"># Have #if($foo) only returns false if $foo is false or
null</span>
+<span class="na">directive.if.emptycheck</span> <span class="o">=</span> <span
class="s">false</span>
+
+<span class="c"># Allow '-' in identifiers</span>
+<span class="na">parser.allows.dash.identifiers</span> <span
class="o">=</span> <span class="s">true</span>
+
+<span class="c"># When displaying null arguments literals, use provided
arguments literals</span>
+<span class="na">velocimacro.preserve.arguments.literals</span> <span
class="o">=</span> <span class="s">true</span>
+</pre></div></div></div>
<hr/>
<div id="copyright">
Copyright © 2016 The Apache Software Foundation, Licensed under
the <a href="http://www.apache.org/licenses/LICENSE-2.0">Apache License,
Version 2.0</a>.<br/>Apache and the Apache feather logo are trademarks of The
Apache Software Foundation.
Modified: velocity/site/production/engine/devel/upgrading.html
URL:
http://svn.apache.org/viewvc/velocity/site/production/engine/devel/upgrading.html?rev=1843925&r1=1843924&r2=1843925&view=diff
==============================================================================
--- velocity/site/production/engine/devel/upgrading.html (original)
+++ velocity/site/production/engine/devel/upgrading.html Mon Oct 15 16:21:07
2018
@@ -223,6 +223,22 @@ h2:hover > .headerlink, h3:hover > .head
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink,
h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink,
dt:hover > .elementid-permalink { visibility: visible }</style>
+<h2 id="upgrading-contents">Upgrading - Contents<a class="headerlink"
href="#upgrading-contents" title="Permanent link">¶</a></h2>
+<div class="toc">
+<ul>
+<li><a href="#upgrading-contents">Upgrading - Contents</a></li>
+<li><a href="#upgrading-from-earlier-versions">Upgrading from earlier
versions</a></li>
+<li><a href="#upgrading-from-velocity-17x-to-velocity-2x">Upgrading from
Velocity 1.7.x to Velocity 2.x</a><ul>
+<li><a href="#behavior-api-changes">Behavior / API changes:</a></li>
+<li><a href="#vtl-changes">VTL Changes:</a></li>
+<li><a href="#dependency-changes">Dependency changes:</a></li>
+</ul>
+</li>
+<li><a href="#upgrading-from-velocity-16x-to-velocity-17x">Upgrading from
Velocity 1.6.x to Velocity 1.7.x</a></li>
+<li><a href="#upgrading-from-velocity-15x-to-velocity-16x">Upgrading from
Velocity 1.5.x to Velocity 1.6.x</a></li>
+<li><a href="#upgrading-from-velocity-14-or-earlier">Upgrading from Velocity
1.4 or earlier</a></li>
+</ul>
+</div>
<h2 id="upgrading-from-earlier-versions">Upgrading from earlier versions<a
class="headerlink" href="#upgrading-from-earlier-versions" title="Permanent
link">¶</a></h2>
<p>Release with the same major number (1.x, 2.x) are intended to be drop-in
replacements. However, in most cases the versions of dependency jars must be
adjusted because newer versions of Velocity might require updates.</p>
<h2 id="upgrading-from-velocity-17x-to-velocity-2x">Upgrading from Velocity
1.7.x to Velocity 2.x<a class="headerlink"
href="#upgrading-from-velocity-17x-to-velocity-2x" title="Permanent
link">¶</a></h2>
@@ -235,10 +251,20 @@ Please note that the maven repository pa
</div>
<p>For busy people: To maximize backward compatibility with Velocity 1.x, be
sure to include the following lines in your Velocity configuration:</p>
-<div class="codehilite"><pre>runtime.conversion.handler = none
-space.gobbling = bc
-directive.if.emptycheck = false
-parser.allows.dash.identifiers = true
+<div class="codehilite"><pre><span class="c"># No automatic conversion of
methods arguments</span>
+<span class="na">runtime.conversion.handler</span> <span class="o">=</span>
<span class="s">none</span>
+
+<span class="c"># Use backward compatible space gobbling</span>
+<span class="na">space.gobbling</span> <span class="o">=</span> <span
class="s">bc</span>
+
+<span class="c"># Have #if($foo) only returns false if $foo is false or
null</span>
+<span class="na">directive.if.emptycheck</span> <span class="o">=</span> <span
class="s">false</span>
+
+<span class="c"># Allow '-' in identifiers</span>
+<span class="na">parser.allows.dash.identifiers</span> <span
class="o">=</span> <span class="s">true</span>
+
+<span class="c"># When displaying null arguments literals, use provided
arguments literals</span>
+<span class="na">velocimacro.preserve.arguments.literals</span> <span
class="o">=</span> <span class="s">true</span>
</pre></div>
@@ -262,14 +288,17 @@ parser.allows.dash.identifiers = true
<li>the macros are now using a 'call by sharing' convention (which means that
all arguments are evaluated once at start, and that the macro receives a copy
of the reference to each argument).</li>
<li>the <code>UberspectLoggable</code> interface has been removed.</li>
<li>the <code>directive.if.tostring.nullcheck</code> configuration property
has been superseded by the <code>directive.if.emptycheck</code> property, which
defaults to true. It means that all empty objects (strings and collections) as
long as zero numbers, do evaluate to false (see the complete <a
href="configuration.html#if-directive">boolean context evaluation</a> rules.).
You may want to set <code>directive.if.emptycheck</code> to false to maximize
backward compatibility with 1.x.</li>
+<li>inside a macro, the rendering of null arguments uses the local reference
literal - to revert to the 1.7 behavior, you can set the boolean property
<code>velocimacro.preserve.arguments.literals</code> to true (since 2.1). The
macros will then use the provided argument literals in such cases.</li>
</ul>
<h3 id="vtl-changes">VTL Changes:<a class="headerlink" href="#vtl-changes"
title="Permanent link">¶</a></h3>
<ul>
-<li>the hypen ( <code>-</code> ) cannot be used in variable names anymore, but
this behavior can be restored for backward compatibility by setting the new
<code>parser.allows.dash.in.identifiers</code> boolean property to true</li>
+<li>the hypen ( <code>-</code> ) cannot be used in variable names anymore, but
this behavior can be restored for backward compatibility (since 2.1) by setting
the new <code>parser.allows.dash.in.identifiers</code> boolean property to
true</li>
<li>method arguments can be arithmetic expressions</li>
<li>method arguments are now converted as needed between all main basic Java
standard types (booleans, numbers and strings). If you want to revert to the
1.x behavior, set the property <code>runtime.conversion.handler =
none</code>.</li>
<li>space gobbling (to control the indentation of generated code) is now
configurable via the <code>space.gobbing</code> configuration key, which can
take the following values: <code>none</code>, <code>bc</code> (aka. backward
compatible), <code>lines</code> and <code>structured</code>. See the related
documentation section for details. To maximize backward compatibility with 1.x,
set it to <code>bc</code>.</li>
-<li>The #foreach predefined references <code>$velocityCount</code> and
<code>$velocityHasNext</code> have been removed. Use
<code>$foreach.count</code> (1-based), <code>$foreach.index</code> (0-based)
and <code>foreach.hasNext()</code>.</li>
+<li>the #foreach predefined references <code>$velocityCount</code> and
<code>$velocityHasNext</code> have been removed. Use
<code>$foreach.count</code> (1-based), <code>$foreach.index</code> (0-based)
and <code>foreach.hasNext()</code>.</li>
+<li>since 2.1, it's now possible to provide default values for references,
using the syntax <code>${name|'John Doe'}</code>. The right part can be any
valid VTL expression.</li>
+<li>since 2.1, the <code>#foreach()</code> directive accepts an
<code>#else</code> block which is evaluated when the loop is empty:
<code>#foreach(...) ... #else ... #end</code>.</li>
</ul>
<h3 id="dependency-changes">Dependency changes:<a class="headerlink"
href="#dependency-changes" title="Permanent link">¶</a></h3>
<ul>
Modified: velocity/site/production/engine/devel/user-guide.html
URL:
http://svn.apache.org/viewvc/velocity/site/production/engine/devel/user-guide.html?rev=1843925&r1=1843924&r2=1843925&view=diff
==============================================================================
--- velocity/site/production/engine/devel/user-guide.html (original)
+++ velocity/site/production/engine/devel/user-guide.html Mon Oct 15 16:21:07
2018
@@ -843,9 +843,12 @@ $foo
</pre></div>
-<p>Velocity also now provides an easy way to tell if you are on the last
iteration of a loop:</p>
+<p>Velocity also provides an easy way to tell if you are on the first or last
iteration of a loop, and also lets you define what happens whenever the loop is
empty:</p>
<div class="codehilite"><pre><span class="cp">#</span><span
class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span
class="nv">customer</span> <span class="o">in</span> <span
class="p">$</span><span class="nv">customerList</span> <span
class="p">)</span><span class="x"></span>
-<span class="x"> </span><span class="p">$</span><span
class="nv">customer</span><span class="p">.</span><span
class="nv">Name</span><span class="cp">#</span><span class="nf">if</span><span
class="p">(</span> <span class="p">$</span><span class="nv">foreach</span><span
class="p">.</span><span class="nv">hasNext</span> <span class="p">)</span><span
class="x">,</span><span class="cp">#</span><span class="nf">end</span><span
class="x"></span>
+<span class="x"> </span><span class="cp">#</span><span
class="nf">if</span><span class="p">(</span> <span class="p">$</span><span
class="nv">foreach</span><span class="p">.</span><span class="nv">first</span>
<span class="p">)</span><span class="x"> There are customer: </span><span
class="cp">#</span><span class="nf">end</span><span class="x"></span>
+<span class="x"> </span><span class="p">$</span><span
class="nv">customer</span><span class="p">.</span><span
class="nv">Name</span><span class="x"> </span><span class="cp">#</span><span
class="nf">if</span><span class="p">(</span> <span class="p">$</span><span
class="nv">foreach</span><span class="p">.</span><span
class="nv">hasNext</span> <span class="p">)</span><span class="x">,</span><span
class="cp">#</span><span class="nf">end</span><span class="x"></span>
+<span class="cp">#</span><span class="nf">else</span><span class="x"></span>
+<span class="x"> Nobody around</span>
<span class="cp">#</span><span class="nf">end</span><span class="x"></span>
</pre></div>
Modified: velocity/site/production/engine/devel/vtl-reference.html
URL:
http://svn.apache.org/viewvc/velocity/site/production/engine/devel/vtl-reference.html?rev=1843925&r1=1843924&r2=1843925&view=diff
==============================================================================
--- velocity/site/production/engine/devel/vtl-reference.html (original)
+++ velocity/site/production/engine/devel/vtl-reference.html Mon Oct 15
16:21:07 2018
@@ -223,16 +223,49 @@ h2:hover > .headerlink, h3:hover > .head
visibility: hidden;
}
h2:hover > .headerlink, h3:hover > .headerlink, h1:hover > .headerlink,
h6:hover > .headerlink, h4:hover > .headerlink, h5:hover > .headerlink,
dt:hover > .elementid-permalink { visibility: visible }</style>
+<h2 id="vtl-reference-contents">VTL Reference - Contents<a class="headerlink"
href="#vtl-reference-contents" title="Permanent link">¶</a></h2>
+<div class="toc">
+<ul>
+<li><a href="#vtl-reference-contents">VTL Reference - Contents</a></li>
+<li><a href="#about-this-guide">About this Guide</a></li>
+<li><a href="#references">References</a><ul>
+<li><a href="#variables">Variables</a></li>
+<li><a href="#properties">Properties</a></li>
+<li><a href="#methods">Methods</a></li>
+</ul>
+</li>
+<li><a href="#directives">Directives</a><ul>
+<li><a href="#set-establishes-the-value-of-a-reference">#set - Establishes the
value of a reference</a></li>
+<li><a
href="#ifelseifelse-output-conditional-on-truth-of-statements">#if/#elseif/#else
- Output conditional on truth of statements</a></li>
+<li><a href="#foreach-loops-through-a-list-of-objects">#foreach - Loops
through a list of objects</a></li>
+<li><a
href="#include-renders-local-files-that-are-not-parsed-by-velocity">#include -
Renders local file(s) that are not parsed by Velocity</a></li>
+<li><a
href="#parse-renders-a-local-template-that-is-parsed-by-velocity">#parse -
Renders a local template that is parsed by Velocity</a></li>
+<li><a href="#stop-stops-the-template-engine">#stop - Stops the template
engine</a></li>
+<li><a href="#break-stops-the-current-directive">#break - Stops the current
directive</a></li>
+<li><a href="#evaluate-dynamically-evaluates-a-string-or-reference">#evaluate
- Dynamically evaluates a string or reference</a></li>
+<li><a href="#define-assigns-a-block-of-vtl-to-a-reference">#define - Assigns
a block of VTL to a reference</a></li>
+<li><a
href="#macro-allows-users-to-define-a-velocimacro-vm-a-repeated-segment-of-a-vtl-template-as-required">#macro
- Allows users to define a Velocimacro (VM), a repeated segment of a VTL
template, as required</a></li>
+</ul>
+</li>
+<li><a href="#comments">Comments</a><ul>
+<li><a href="#single-line-comments">Single Line Comments</a></li>
+<li><a href="#multi-line-comments">Multi Line Comments</a></li>
+</ul>
+</li>
+<li><a href="#unparsed-content">Unparsed Content</a></li>
+</ul>
+</div>
<h2 id="about-this-guide">About this Guide<a class="headerlink"
href="#about-this-guide" title="Permanent link">¶</a></h2>
<p>This guide is the reference for the Velocity Template Language (VTL). For
more information, please also refer to the <a href="user-guide.html">Velocity
User Guide</a>.</p>
+<p>Notations are given in a very approximative EBNF-like syntax, the goal is
to remain readable.</p>
<h2 id="references">References<a class="headerlink" href="#references"
title="Permanent link">¶</a></h2>
<p>In the following syntax references, <em>identifier</em> refers to:</p>
-<p>( <strong>a..z</strong>, <strong>A..Z</strong>, <strong>_</strong> ) [ (
<strong>a..z</strong>, <strong>A..Z</strong>, <strong>0..9</strong>,
<strong>_</strong> ) , ( <strong>a..z</strong>, <strong>A..Z</strong>,
<strong>0..9</strong>, <strong>_</strong> ), ... ]</p>
+<p><span class="blue">(</span> <strong>a..z</strong> <span class="bigger
blue">|</span> <strong>A..Z</strong> <span class="bigger blue">|</span>
<strong>_</strong> <span class="blue">)</span> <span class="blue">[</span>
<span class="blue">(</span> <strong>a..z</strong> <span class="bigger
blue">|</span> <strong>A..Z</strong> <span class="bigger blue">|</span>
<strong>0..9</strong> <span class="bigger blue">|</span> <strong>_</strong>
<span class="blue">)</span> <span class="blue">,</span> <span
class="blue">(</span> <strong>a..z</strong> <span class="bigger blue">|</span>
<strong>A..Z</strong> <span class="bigger blue">|</span> <strong>0..9</strong>
<span class="bigger blue">|</span> <strong>_</strong> <span class="blue">),
...</span> <span class="blue">]</span></p>
<p>that is, a letter or an underscore followed by any number of letters,
numbers and underscores.</p>
<p>If the <code>parser.allows.dash.identifiers</code> configuration value is
set to true, then the <strong>-</strong> dash is also allowed in identifiers
(and must be surrounded by spaces to be interpreted as an arithmetic minus
operator).</p>
<h3 id="variables">Variables<a class="headerlink" href="#variables"
title="Permanent link">¶</a></h3>
<p>Notation:</p>
-<p><strong>$</strong> [ <strong>!</strong> ] [ <strong>{</strong> ]
<em>identifier</em> [ [ <strong>|</strong> <em>alternate value</em> ]
<strong>}</strong> ]</p>
+<p><strong>$</strong> <span class="blue">[</span> <strong>!</strong> <span
class="blue">]</span> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <em>identifier</em> <span class="blue">[</span> <span
class="blue">[</span> <strong>|</strong> <em>alternate value</em> <span
class="blue">]</span> <strong>}</strong> <span class="blue">]</span></p>
<p>Usage:</p>
<ul>
<li><em>alternate value</em>: alternate expression to use if the reference is
null, empty, false or zero</li>
@@ -248,7 +281,7 @@ h2:hover > .headerlink, h3:hover > .head
<p><em>Note that for backward compatibility reasons, it's possible to enable
'<strong><code>-</code></strong>' as a valid character in variables
identifiers, <a href="configuration.html#parser-configuration">see the parser
configuration section</a>.</em></p>
<h3 id="properties">Properties<a class="headerlink" href="#properties"
title="Permanent link">¶</a></h3>
<p>Notation:</p>
-<p><strong>$</strong> [ <strong>{</strong> ] <em>identifier</em>
<strong>.</strong> <em>identifier</em> [ [ <strong>|</strong> <em>alternate
value</em> ] <strong>}</strong> ]</p>
+<p><strong>$</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <em>identifier</em> <strong>.</strong>
<em>identifier</em> <span class="blue">[</span> <span class="blue">[</span>
<strong>|</strong> <em>alternate value</em> <span class="blue">]</span>
<strong>}</strong> <span class="blue">]</span></p>
<p>Usage:</p>
<ul>
<li><em>alternate value</em>: alternate expression to use if the property is
null, empty, false or zero</li>
@@ -261,7 +294,7 @@ h2:hover > .headerlink, h3:hover > .head
</ul>
<h3 id="methods">Methods<a class="headerlink" href="#methods" title="Permanent
link">¶</a></h3>
<p>Notation:</p>
-<p><strong>$</strong> [ <strong>{</strong> ] <em>identifier</em>
<strong>.</strong> <em>identifier</em> <strong>(</strong> [ <em>parameter
list...</em> ] <strong>)</strong> [ [ <strong>|</strong> <em>alternate
value</em> ] <strong>}</strong> ]</p>
+<p><strong>$</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <em>identifier</em> <strong>.</strong>
<em>identifier</em> <strong>(</strong> <span class="blue">[</span>
<em>parameter list...</em> <span class="blue">]</span> <strong>)</strong> <span
class="blue">[</span> <span class="blue">[</span> <strong>|</strong>
<em>alternate value</em> <span class="blue">]</span> <strong>}</strong> <span
class="blue">]</span></p>
<p>Usage:</p>
<ul>
<li><em>alternate value</em>: alternate expression to use if the method
returns null, empty, false or zero</li>
@@ -279,11 +312,11 @@ h2:hover > .headerlink, h3:hover > .head
<h2 id="directives">Directives<a class="headerlink" href="#directives"
title="Permanent link">¶</a></h2>
<h3 id="set-establishes-the-value-of-a-reference">#set - Establishes the value
of a reference<a class="headerlink"
href="#set-establishes-the-value-of-a-reference" title="Permanent
link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>set</strong> [
<strong>}</strong> ] <strong>(</strong> <em>$ref</em> <strong>=</strong> [
<strong>"</strong>, <strong>'</strong> ] <em>arg</em> [ <strong>"</strong>,
<strong>'</strong> ] )</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>set</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong> <em>$ref</em>
<strong>=</strong> <span class="blue">[</span> <strong>"</strong>,
<strong>'</strong> <span class="blue">]</span> <em>arg</em> <span
class="blue">[</span> <strong>"</strong>, <strong>'</strong> <span
class="blue">]</span> )</p>
<p>Usage:</p>
<ul>
<li><em>$ref</em> - The LHS of the assignment must be a variable reference or
a property reference.</li>
-<li><em>arg</em> - The RHS of the assignment, <em>arg</em> is parsed if
enclosed in double quotes, and not parsed if enclosed in single quotes. If the
RHS evaluates to <em>null</em>, it is <strong>not</strong> assigned to the
LHS.</li>
+<li><em>arg</em> - The RHS of the assignment, <em>arg</em> is parsed (i.e.
interpolated) if enclosed in double quotes, and not parsed if enclosed in
single quotes. If the RHS evaluates to <em>null</em>, it is
<strong>not</strong> assigned to the LHS.</li>
</ul>
<p>Examples:</p>
<ul>
@@ -306,11 +339,11 @@ h2:hover > .headerlink, h3:hover > .head
</ul>
<h3
id="ifelseifelse-output-conditional-on-truth-of-statements">#if/#elseif/#else -
Output conditional on truth of statements<a class="headerlink"
href="#ifelseifelse-output-conditional-on-truth-of-statements" title="Permanent
link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>if</strong> [
<strong>}</strong> ] <strong>(</strong> <em>condition</em> <strong>)</strong>
<em>output</em> [<strong>#</strong> [ <strong>{</strong> ]
<strong>elseif</strong> [ <strong>}</strong> ] <strong>(</strong>
<em>condition</em> <strong>)</strong> <em>output</em> ] [ <strong>#</strong> [
<strong>{</strong> ] <strong>else</strong> [ <strong>}</strong> ]
<em>output</em> ] <strong>#</strong> [ <strong>{</strong> ]
<strong>end</strong> [ <strong>}</strong> ]</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>if</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong>
<em>condition</em> <strong>)</strong> <em>output</em> [<strong>#</strong> <span
class="blue">[</span> <strong>{</strong> <span class="blue">]</span>
<strong>elseif</strong> <span class="blue">[</span> <strong>}</strong> <span
class="blue">]</span> <strong>(</strong> <em>condition</em> <strong>)</strong>
<em>output</em> <span class="blue">]</span> <span class="blue">[</span>
<strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>else</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <em>output</em> <span
class="blue">]</span> <strong>#</strong> <span class="blue">[</span>
<strong>{</strong> <span class="blue">]</span> <strong>end</strong> <span
class="blue">[</span> <strong>}</strong> <span class
="blue">]</span></p>
<p>Usage:</p>
<ul>
<li>
-<p><em>condition</em> - Expression to evaluate. When tis result is null,
evaluate to false. Otherwise, check for conversion towards Boolean and
non-emptiness as follow:</p>
+<p><em>condition</em> - Expression to evaluate. When its result is null,
evaluate to false. Otherwise, check for conversion towards Boolean and
non-emptiness as follow:</p>
<ul>
<li>return its value for a Boolean object, or the result of the getAsBoolean()
method if it exists.</li>
<li>if <code>directive.if.emptycheck</code> = <code>false</code>
(<code>true</code> by default), stop here and consider it true.</li>
@@ -406,29 +439,30 @@ h2:hover > .headerlink, h3:hover > .head
</ol>
<h3 id="foreach-loops-through-a-list-of-objects">#foreach - Loops through a
list of objects<a class="headerlink"
href="#foreach-loops-through-a-list-of-objects" title="Permanent
link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>foreach</strong> [
<strong>}</strong> ] <strong>(</strong> <em>$ref</em> <strong>in</strong>
<em>arg</em> <strong>)</strong> <em>statement</em> <strong>#</strong> [
<strong>{</strong> ] <strong>end</strong> [ <strong>}</strong> ]</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>foreach</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong> <em>$ref</em>
<strong>in</strong> <em>arg</em> <strong>)</strong> <em>statements</em> <span
class="blue">[</span> <strong>#</strong> <span class="blue">[</span>
<strong>{</strong> <span class="blue">]</span> <strong>else</strong> <span
class="blue">[</span> <strong>}</strong> <span class="blue">]</span>
<em>alternate statements</em> <span class="blue">]</span> <strong>#</strong>
<span class="blue">[</span> <strong>{</strong> <span class="blue">]</span>
<strong>end</strong> <span class="blue">[</span> <strong>}</strong> <span
class="blue">]</span></p>
<p>Usage:</p>
<ul>
<li><em>$ref</em> - The first variable reference is the item.</li>
<li><em>arg</em> - May be one of the following: a reference to a list (i.e.
object array, collection, or map), an array list, or the range operator.</li>
-<li><em>statement</em> - What is output each time Velocity finds a valid item
in the list denoted above as <em>arg</em>. This output is any valid VTL and is
rendered each iteration of the loop.</li>
+<li><em>statements</em> - What is output each time Velocity finds a valid item
in the list denoted above as <em>arg</em>. This output is any valid VTL and is
rendered each iteration of the loop.</li>
+<li><em>alternate statements</em> - What is to display whenever Velocity did
not enter the loop (when <em>arg</em> is null, empty, or doesn't have any valid
iterator).</li>
</ul>
-<p>Examples of the #foreach(), omitting the statement block :</p>
+<p>Examples of the #foreach loop:</p>
<ul>
-<li>Reference: <code>#foreach ( $item in $items )</code></li>
-<li>Array list: <code>#foreach ( $item in ["Not", $my, "fault"] )</code></li>
-<li>Range operator: <code>#foreach ( $item in [1..3] )</code></li>
-</ul>
-<p>Velocity provides an easy way to get the loop counter so that you can do
something like the following:</p>
-<div class="codehilite"><pre><span class="p"><</span><span
class="nt">table</span><span class="p">></span>
-<span class="cp">#</span><span class="nf">foreach</span><span
class="p">(</span> <span class="p">$</span><span class="nv">customer</span>
<span class="o">in</span> <span class="p">$</span><span
class="nv">customerList</span> <span class="p">)</span>
- <span class="p"><</span><span class="nt">tr</span><span
class="p">><</span><span class="nt">td</span><span
class="p">>$</span><span class="nv">foreach</span><span
class="p">.</span><span class="nv">count</span><span
class="p"></</span><span class="nt">td</span><span
class="p">><</span><span class="nt">td</span><span
class="p">>$</span><span class="nv">customer</span><span
class="p">.</span><span class="nv">Name</span><span class="p"></</span><span
class="nt">td</span><span class="p">></</span><span
class="nt">tr</span><span class="p">></span>
-<span class="cp">#</span><span class="nf">end</span>
-<span class="p"></</span><span class="nt">table</span><span
class="p">></span>
-</pre></div>
-
-
-<p>Additionally, the maximum allowed number of loop iterations can be
controlled engine-wide with <code>velocity.properties</code>. By default, there
is no limit:</p>
+<li>Reference: <code>#foreach ( $item in $items ) $item #else no item
#end</code></li>
+<li>Array list: <code>#foreach ( $item in ["Not", $my, "fault"] ) $item
#end</code></li>
+<li>Range operator: <code>#foreach ( $item in [1..3] ) $item #end</code></li>
+</ul>
+<p>Inside the #foreach loop, the following can be used:</p>
+<ul>
+<li><code>$foreach.count</code> : 1-based loop index</li>
+<li><code>$foreach.index</code> : 0-based loop index</li>
+<li><code>$foreach.first</code> : true on the first iteration</li>
+<li><code>$foreach.last</code> : true on the last iteration</li>
+<li><code>$foreach.hasNext</code> : false on the last iteration</li>
+<li><code>$foreach.stop()</code> : exists the loop, synonym for
<code>#break</code></li>
+</ul>
+<p>The maximum allowed number of loop iterations can be controlled engine-wide
with <code>velocity.properties</code>. By default, there is no limit:</p>
<div class="codehilite"><pre><span class="c"># The maximum allowed number of
loops.</span>
<span class="na">directive.foreach.maxloops</span> <span class="o">=</span>
<span class="s">-1</span>
</pre></div>
@@ -436,7 +470,7 @@ h2:hover > .headerlink, h3:hover > .head
<h3 id="include-renders-local-files-that-are-not-parsed-by-velocity">#include
- Renders local file(s) that are not parsed by Velocity<a class="headerlink"
href="#include-renders-local-files-that-are-not-parsed-by-velocity"
title="Permanent link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>include</strong> [
<strong>}</strong> ] <strong>(</strong> <em>arg</em> [ <em>arg2</em> ...
<em>argn</em> ] <strong>)</strong></p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>include</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong> <em>arg</em>
<span class="blue">[</span> <em>arg2</em> ... <em>argn</em> <span
class="blue">]</span> <strong>)</strong></p>
<p>Usage:</p>
<ul>
<li><em>arg</em> - Refers to a valid file under TEMPLATE_ROOT.</li>
@@ -448,7 +482,7 @@ h2:hover > .headerlink, h3:hover > .head
</ul>
<h3 id="parse-renders-a-local-template-that-is-parsed-by-velocity">#parse -
Renders a local template that is parsed by Velocity<a class="headerlink"
href="#parse-renders-a-local-template-that-is-parsed-by-velocity"
title="Permanent link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>parse</strong> [
<strong>}</strong> ] <strong>(</strong> <em>arg</em> <strong>)</strong></p></p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>parse</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong> <em>arg</em>
<strong>)</strong></p></p>
<p>Usage:</p>
<ul>
<li><em>arg</em> - Refers to a template under TEMPLATE_ROOT.</li>
@@ -461,17 +495,17 @@ h2:hover > .headerlink, h3:hover > .head
<p>Recursion permitted. See <em>parse_directive.maxdepth</em> in
<code>velocity.properties</code> to change from parse depth. (The default parse
depth is 10.)</p>
<h3 id="stop-stops-the-template-engine">#stop - Stops the template engine<a
class="headerlink" href="#stop-stops-the-template-engine" title="Permanent
link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>stop</strong> [
<strong>}</strong> ]</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>stop</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span></p>
<p>Usage:</p>
<p>This will stop execution of the current template. This is good for
debugging a template.</p>
<h3 id="break-stops-the-current-directive">#break - Stops the current
directive<a class="headerlink" href="#break-stops-the-current-directive"
title="Permanent link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>break</strong> [
<strong>}</strong> ]</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>break</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span></p>
<p>Usage:</p>
<p>This will break execution of the current content directive. This is good
for exiting a #foreach loop early, but also works in other scopes. You can even
pass the scope control reference for a specific outer scope to break execution
of all scopes outward to the specified one.</p>
<h3 id="evaluate-dynamically-evaluates-a-string-or-reference">#evaluate -
Dynamically evaluates a string or reference<a class="headerlink"
href="#evaluate-dynamically-evaluates-a-string-or-reference" title="Permanent
link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>evaluate</strong> [
<strong>}</strong> ] <strong>(</strong> <em>arg</em> <strong>)</strong></p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>evaluate</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong> <em>arg</em>
<strong>)</strong></p>
<p>Usage:</p>
<ul>
<li><em>arg</em> - String literal or reference to be dynamically
evaluated.</li>
@@ -483,7 +517,7 @@ h2:hover > .headerlink, h3:hover > .head
</ul>
<h3 id="define-assigns-a-block-of-vtl-to-a-reference">#define - Assigns a
block of VTL to a reference<a class="headerlink"
href="#define-assigns-a-block-of-vtl-to-a-reference" title="Permanent
link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>define</strong> [
<strong>}</strong> ] <strong>(<em> </em>$ref* </strong>)<strong>
<em>statement</em> </strong>#<strong> [ </strong>{<strong> ]
</strong>end<strong> [ </strong>}** ]</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>define</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong> <em>$ref</em>
<strong>)</strong> <em>statement</em> <strong>#</strong> <span
class="blue">[</span> <strong>{</strong> <span class="blue">]</span>
<strong>end</strong> <span class="blue">[</span> <strong>}</strong> <span
class="blue">]</span></p>
<p>Usage:</p>
<ul>
<li><em>$ref</em> - Reference that is assigned the VTL block as a value.</li>
@@ -495,11 +529,11 @@ h2:hover > .headerlink, h3:hover > .head
</ul>
<h3
id="macro-allows-users-to-define-a-velocimacro-vm-a-repeated-segment-of-a-vtl-template-as-required">#macro
- Allows users to define a Velocimacro (VM), a repeated segment of a VTL
template, as required<a class="headerlink"
href="#macro-allows-users-to-define-a-velocimacro-vm-a-repeated-segment-of-a-vtl-template-as-required"
title="Permanent link">¶</a></h3>
<p>Format:</p>
-<p><strong>#</strong> [ <strong>{</strong> ] <strong>macro</strong> [
<strong>}</strong> ] <strong>(</strong> <em>vmname</em> <em>$arg1</em> [
<strong>=</strong> <em>def1</em> ] [ <em>$arg2</em> [ <strong>=</strong>
<em>def2</em> ] <em>$arg3</em> [ <strong>=</strong> def3 ] ... <em>$argn</em> [
<strong>=</strong> <em>defn</em> ] ] <strong>)</strong> [ <em>VTL code</em> ]
<strong>#</strong> [ <strong>{</strong> ] <strong>end</strong> [
<strong>}</strong> ]</p>
+<p><strong>#</strong> <span class="blue">[</span> <strong>{</strong> <span
class="blue">]</span> <strong>macro</strong> <span class="blue">[</span>
<strong>}</strong> <span class="blue">]</span> <strong>(</strong>
<em>vmname</em> <em>$arg1</em> <span class="blue">[</span> <strong>=</strong>
<em>def1</em> <span class="blue">]</span> <span class="blue">[</span>
<em>$arg2</em> <span class="blue">[</span> <strong>=</strong> <em>def2</em>
<span class="blue">]</span> <em>$arg3</em> <span class="blue">[</span>
<strong>=</strong> def3 <span class="blue">]</span> ... <em>$argn</em> <span
class="blue">[</span> <strong>=</strong> <em>defn</em> <span
class="blue">]</span> ] <strong>)</strong> <span class="blue">[</span> <em>VTL
code</em> <span class="blue">]</span> <strong>#</strong> <span
class="blue">[</span> <strong>{</strong> <span class="blue">]</span>
<strong>end</strong> <span class="blue">[</span> <strong>}</strong> <span
class="blue">]</span></p>
<p>Usage:</p>
<ul>
<li><em>vmname</em> - Name used to call the VM (<em>#vmname</em>)</li>
-<li><em>$arg1 $arg2 [ ... ]</em> - Arguments to the VM. There can be any
number of arguments, but the number used at invocation must match the number
specified in the definition, unless there is a default value provided for
missing parameters.</li>
+<li><em>$arg1 $arg2</em> ... - Arguments to the VM. There can be any number of
arguments, but the number used at invocation must match the number specified in
the definition, unless there is a default value provided for missing
parameters.</li>
<li><em>def1, def2, ...</em> - Optional default values provided for macro
arguments. If a default value is provided for an argument, a default value must
also be provided to all subsequent arguments.</li>
<li><em>VTL code</em> - Any valid VTL code, anything you can put into a
template, can be put into a VM.</li>
</ul>
@@ -518,6 +552,13 @@ h2:hover > .headerlink, h3:hover > .head
<li><em>Template library:</em> can be either VMs pre-packaged with Velocity or
custom-made, user-defined, site-specific VMs; available from any template</li>
<li><em>Inline:</em> found in regular templates, only usable when
<em>velocimacro.permissions.allowInline=true</em> in
<code>velocity.properties</code>.</li>
</ol>
+<p>Since 2.0, when a macro argument is null or invalid, its rendering will
display its local name. The following block of code:</p>
+<div class="codehilite"><pre><span class="cp">#</span><span
class="nf">macro</span><span class="p">(</span> <span class="nf">vmname</span>
<span class="p">$</span><span class="nv">foo</span> <span
class="p">)</span><span class="x"> </span><span class="p">$</span><span
class="nv">foo</span><span class="x"> </span><span class="cp">#</span><span
class="nf">end</span><span class="x"></span>
+<span class="cp">#</span><span class="nf">vmname</span><span
class="p">(</span> <span class="p">$</span><span class="nv">null</span> <span
class="p">)</span><span class="x"></span>
+</pre></div>
+
+
+<p>will display <code>$foo</code>. If you wish to revert to the 1.x behavior
(which is to display <code>$null</code>), you can set the
<code>velocimacro.preserve.arguments.literals</code> configuration property to
true (since 2.1).</p>
<h2 id="comments">Comments<a class="headerlink" href="#comments"
title="Permanent link">¶</a></h2>
<p>Comments are not rendered at runtime.</p>
<h3 id="single-line-comments">Single Line Comments<a class="headerlink"
href="#single-line-comments" title="Permanent link">¶</a></h3>