You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@velocity.apache.org by cb...@apache.org on 2018/10/15 16:21:08 UTC

svn commit: r1843925 - in /velocity/site/production: css/site.css engine/devel/changes.html engine/devel/configuration.html engine/devel/upgrading.html engine/devel/user-guide.html engine/devel/vtl-reference.html

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">&para;</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">&para;</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">&para;</a></h2>
+<h3 id="resource-loading">Resource loading<a class="headerlink" href="#resource-loading" title="Permanent link">&para;</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">&para;</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 &#39;-&#39; 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 &#169; 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">&para;</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">&para;</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">&para;</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 &#39;-&#39; 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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&lt;</span><span class="nt">table</span><span class="p">&gt;</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">&lt;</span><span class="nt">tr</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;$</span><span class="nv">foreach</span><span class="p">.</span><span class="nv">count</span><span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;&lt;</span><span class="nt">td</span><span class="p">&gt;$</span><span class="nv">customer</span><span class="p">.</span><span class="nv">Name</span><span class="p">&lt;/</span><span class="nt">td</span><span class="p">&gt;&lt;/</span><span class="nt">tr</span><span class="p">&gt;</span>
-<span class="cp">#</span><span class="nf">end</span>
-<span class="p">&lt;/</span><span class="nt">table</span><span class="p">&gt;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</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">&para;</a></h3>