Modified: velocity/site/production/engine/devel/user-guide.html URL: http://svn.apache.org/viewvc/velocity/site/production/engine/devel/user-guide.html?rev=1834366&r1=1834365&r2=1834366&view=diff ============================================================================== --- velocity/site/production/engine/devel/user-guide.html (original) +++ velocity/site/production/engine/devel/user-guide.html Mon Jun 25 18:46:53 2018 @@ -336,7 +336,7 @@ h2:hover > .headerlink, h3:hover > .head <h2 id="velocity-template-language-vtl-an-introduction">Velocity Template Language (VTL): An Introduction<a class="headerlink" href="#velocity-template-language-vtl-an-introduction" title="Permanent link">¶</a></h2> <p>The Velocity Template Language (VTL) is meant to provide the easiest, simplest, and cleanest way to incorporate dynamic content in a web page. Even a web page developer with little or no programming experience should soon be capable of using VTL to incorporate dynamic content in a web site.</p> <p>VTL uses <em>references</em> to embed dynamic content in a web site, and a variable is one type of reference. Variables are one type of reference that can refer to something defined in the Java code, or it can get its value from a VTL <em>statement</em> in the web page itself. Here is an example of a VTL statement that could be embedded in an HTML document:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">a</span> <span class="o">=</span> <span class="s2">"Velocity"</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $a = "Velocity" ) </pre></div> @@ -411,76 +411,76 @@ visible. *# This text is outside the com <li>underscore ("_")</li> </ul> <p>Here are some examples of valid variable references in the VTL:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">foo</span><span class="x"></span> -<span class="p">$</span><span class="nv">mudSlinger</span><span class="x"></span> -<span class="p">$</span><span class="nv">mud</span><span class="x">-slinger</span> -<span class="p">$</span><span class="nv">mud_slinger</span><span class="x"></span> -<span class="p">$</span><span class="nv">mudSlinger1</span><span class="x"></span> +<div class="codehilite"><pre>$foo +$mudSlinger +$mud-slinger +$mud_slinger +$mudSlinger1 </pre></div> <p>When VTL references a variable, such as <em>$foo</em>, the variable can get its value from either a <em>set</em> directive in the template, or from the Java code. For example, if the Java variable <em>$foo</em> has the value <em>bar</em> at the time the template is requested, <em>bar</em> replaces all instances of <em>$foo</em> on the web page. Alternatively, if I include the statement</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="s2">"bar"</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $foo = "bar" ) </pre></div> <p>The output will be the same for all instances of <em>$foo</em> that follow this directive.</p> <h3 id="properties">Properties<a class="headerlink" href="#properties" title="Permanent link">¶</a></h3> <p>The second flavor of VTL references are properties, and properties have a distinctive format. The shorthand notation consists of a leading <em>$</em> character followed a VTL Identifier, followed by a dot character (".") and another VTL Identifier. These are examples of valid property references in the VTL:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">customer</span><span class="p">.</span><span class="nv">Address</span><span class="x"></span> -<span class="p">$</span><span class="nv">purchase</span><span class="p">.</span><span class="nv">Total</span><span class="x"></span> +<div class="codehilite"><pre>$customer.Address +$purchase.Total </pre></div> <p>Take the first example, <em>$customer.Address</em>. It can have two meanings. It can mean, Look in the hashtable identified as <em>customer</em> and return the value associated with the key <em>Address</em>. But <em>$customer.Address</em> can also be referring to a method (references that refer to methods will be discussed in the next section); <em>$customer.Address</em> could be an abbreviated way of writing <em>$customer.getAddress()</em>. When your page is requested, Velocity will determine which of these two possibilities makes sense, and then return the appropriate value.</p> <h3 id="methods">Methods<a class="headerlink" href="#methods" title="Permanent link">¶</a></h3> <p>A method is defined in the Java code and is capable of doing something useful, like running a calculation or arriving at a decision. Methods are references that consist of a leading "$" character followed a VTL Identifier, followed by a VTL <em>Method Body</em>. A VTL Method Body consists of a VTL Identifier followed by an left parenthesis character ("("), followed by an optional parameter list, followed by right parenthesis character (")"). These are examples of valid method references in the VTL:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">customer</span><span class="p">.</span><span class="nv">getAddress</span><span class="p">()</span><span class="x"></span> -<span class="p">$</span><span class="nv">purchase</span><span class="p">.</span><span class="nv">getTotal</span><span class="p">()</span><span class="x"></span> -<span class="p">$</span><span class="nv">page</span><span class="p">.</span><span class="nv">setTitle</span><span class="p">(</span> <span class="s2">"My Home Page"</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">person</span><span class="p">.</span><span class="nv">setAttributes</span><span class="p">(</span> <span class="p">[</span><span class="s2">"Strange"</span><span class="p">,</span> <span class="s2">"Weird"</span><span class="p">,</span> <span class="s2">"Excited"</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>$customer.getAddress() +$purchase.getTotal() +$page.setTitle( "My Home Page" ) +$person.setAttributes( ["Strange", "Weird", "Excited"] ) </pre></div> <p>The first two examples -- <em>$customer.getAddress()</em> and <em>$purchase.getTotal()</em> -- may look similar to those used in the Properties section above, <em>$customer.Address</em> and <em>$purchase.Total</em>. If you guessed that these examples must be related some in some fashion, you are correct!</p> <p>VTL Properties can be used as a shorthand notation for VTL Methods. The Property <em>$customer.Address</em> has the exact same effect as using the Method <em>$customer.getAddress()</em>. It is generally preferable to use a Property when available. The main difference between Properties and Methods is that you can specify a parameter list to a Method.</p> <p>The shorthand notation can be used for the following Methods</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">sun</span><span class="p">.</span><span class="nv">getPlanets</span><span class="p">()</span><span class="x"></span> -<span class="p">$</span><span class="nv">annelid</span><span class="p">.</span><span class="nv">getDirt</span><span class="p">()</span><span class="x"></span> -<span class="p">$</span><span class="nv">album</span><span class="p">.</span><span class="nv">getPhoto</span><span class="p">()</span><span class="x"></span> +<div class="codehilite"><pre>$sun.getPlanets() +$annelid.getDirt() +$album.getPhoto() </pre></div> <p>We might expect these methods to return the names of planets belonging to the sun, feed our earthworm, or get a photograph from an album. Only the long notation works for the following Methods.</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">sun</span><span class="p">.</span><span class="nv">getPlanet</span><span class="p">(</span> <span class="p">[</span><span class="s2">"Earth"</span><span class="p">,</span> <span class="s2">"Mars"</span><span class="p">,</span> <span class="s2">"Neptune"</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> -<span class="cp">##</span><span class="c"> Can't pass a parameter list with $sun.Planets</span><span class="x"></span> +<div class="codehilite"><pre>$sun.getPlanet( ["Earth", "Mars", "Neptune"] ) +## Can't pass a parameter list with $sun.Planets -<span class="p">$</span><span class="nv">sisyphus</span><span class="p">.</span><span class="nv">pushRock</span><span class="p">()</span><span class="x"></span> -<span class="cp">##</span><span class="c"> Velocity assumes I mean $sisyphus.getRock()</span><span class="x"></span> +$sisyphus.pushRock() +## Velocity assumes I mean $sisyphus.getRock() -<span class="p">$</span><span class="nv">book</span><span class="p">.</span><span class="nv">setTitle</span><span class="p">(</span> <span class="s2">"Homage to Catalonia"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">##</span><span class="c"> Can't pass a parameter</span><span class="x"></span> +$book.setTitle( "Homage to Catalonia" ) +## Can't pass a parameter </pre></div> <p>All array references are treated as if they are fixed-length lists. This means that you can call java.util.List methods and properties on array references. So, if you have a reference to an array (let's say this one is a String[] with three values), you can do:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">myarray</span><span class="p">.</span><span class="nv">isEmpty</span><span class="p">()</span><span class="x"> or </span><span class="p">$</span><span class="nv">myarray</span><span class="p">.</span><span class="nv">empty</span><span class="x"></span> +<div class="codehilite"><pre>$myarray.isEmpty() or $myarray.empty -<span class="p">$</span><span class="nv">myarray</span><span class="p">.</span><span class="nv">size</span><span class="p">()</span><span class="x"></span> +$myarray.size() -<span class="p">$</span><span class="nv">myarray</span><span class="p">.</span><span class="nv">get</span><span class="p">(</span><span class="m">2</span><span class="p">)</span><span class="x"></span> +$myarray.get(2) -<span class="p">$</span><span class="nv">myarray</span><span class="p">.</span><span class="nv">set</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="s1">'test'</span><span class="p">)</span><span class="x"></span> +$myarray.set(1, 'test') </pre></div> <p>Velocity also supports vararg methods. A method like <code>azpublic void setPlanets(String... planets)</code> or even just <code>public void setPlanets(String[] planets)</code> can now accept any number of arguments when called in a template.</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">sun</span><span class="p">.</span><span class="nv">setPlanets</span><span class="p">(</span><span class="s1">'Earth'</span><span class="p">,</span> <span class="s1">'Mars'</span><span class="p">,</span> <span class="s1">'Neptune'</span><span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>$sun.setPlanets('Earth', 'Mars', 'Neptune') -<span class="p">$</span><span class="nv">sun</span><span class="p">.</span><span class="nv">setPlanets</span><span class="p">(</span><span class="s1">'Mercury'</span><span class="p">)</span><span class="x"></span> +$sun.setPlanets('Mercury') -<span class="p">$</span><span class="nv">sun</span><span class="p">.</span><span class="nv">setPlanets</span><span class="p">()</span><span class="x"></span> -<span class="cp">##</span><span class="c"> Will just pass in an empty, zero-length array</span><span class="x"></span> +$sun.setPlanets() +## Will just pass in an empty, zero-length array </pre></div> @@ -504,24 +504,24 @@ visible. *# This text is outside the com <p>The final value resulting from each and every reference (whether variable, property, or method) is converted to a String object when it is rendered into the final output. If there is an object that represents <em>$foo</em> (such as an Integer object), then Velocity will call its <code>.toString()</code> method to resolve the object into a String.</p> <h3 id="index-notation">Index Notation<a class="headerlink" href="#index-notation" title="Permanent link">¶</a></h3> <p>Using the notation of the form <code>$foo[0]</code> can be used to access a given index of an object. This form is synonymous with calling the get(Object) method on a given object i.e, <code>$foo.get(0)</code>, and provides essentially a syntactic shorthand for such operations. Since this simply calls the get method all of the following are valid uses:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">foo</span><span class="x">[0] </span><span class="cp">##</span><span class="c"> $foo takes in an Integer look up</span><span class="x"></span> -<span class="p">$</span><span class="nv">foo</span><span class="x">[</span><span class="p">$</span><span class="nv">i</span><span class="x">] </span><span class="cp">##</span><span class="c"> Using another reference as the index </span><span class="x"></span> -<span class="p">$</span><span class="nv">foo</span><span class="x">["bar"] </span><span class="cp">##</span><span class="c"> Passing a string where $foo may be a Map</span><span class="x"></span> +<div class="codehilite"><pre>$foo[0] ## $foo takes in an Integer look up +$foo[$i] ## Using another reference as the index +$foo["bar"] ## Passing a string where $foo may be a Map </pre></div> <p>The bracketed syntax also works with Java arrays since Velocity wraps arrays in an access object that provides a <code>get(Integer)</code> method which returns the specified element.</p> <p>The bracketed syntax is valid anywhere <code>.get</code> is valid, for example:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">foo</span><span class="p">.</span><span class="nv">bar</span><span class="x">[1].junk</span> -<span class="p">$</span><span class="nv">foo</span><span class="p">.</span><span class="nv">callMethod</span><span class="p">()</span><span class="x">[1]</span> -<span class="p">$</span><span class="nv">foo</span><span class="x">["apple"][4]</span> +<div class="codehilite"><pre>$foo.bar[1].junk +$foo.callMethod()[1] +$foo["apple"][4] </pre></div> <p>A reference can also be set using index notation, for example:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">foo</span><span class="o">[</span><span class="m">0</span><span class="p">]</span> <span class="o">=</span> <span class="m">1</span><span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">foo</span><span class="p">.</span><span class="nv">bar</span><span class="o">[</span><span class="m">1</span><span class="p">]</span> <span class="o">=</span> <span class="m">3</span><span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">map</span><span class="o">[</span><span class="s2">"apple"</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"orange"</span><span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set($foo[0] = 1) +#set($foo.bar[1] = 3) +#set($map["apple"] = "orange") </pre></div> @@ -536,7 +536,7 @@ visible. *# This text is outside the com <p>In almost all cases you will use the shorthand notation for references, but in some cases the formal notation is required for correct processing.</p> <p>Suppose you were constructing a sentence on the fly where <em>$vice</em> was to be used as the base word in the noun of a sentence. The goal is to allow someone to choose the base word and produce one of the two following results: "Jack is a pyromaniac." or "Jack is a kleptomaniac.". Using the shorthand notation would be inadequate for this task. Consider the following example:</p> -<div class="codehilite"><pre><span class="x">Jack is a </span><span class="p">$</span><span class="nv">vicemaniac</span><span class="x">.</span> +<div class="codehilite"><pre>Jack is a $vicemaniac. </pre></div> @@ -548,7 +548,7 @@ visible. *# This text is outside the com <p>Now Velocity knows that <em>$vice</em>, not <em>$vicemaniac</em>, is the reference. Formal notation is often useful when references are directly adjacent to text in a template.</p> <h2 id="quiet-reference-notation">Quiet Reference Notation<a class="headerlink" href="#quiet-reference-notation" title="Permanent link">¶</a></h2> <p>When Velocity encounters an undefined reference, its normal behavior is to output the image of the reference. For example, suppose the following reference appears as part of a VTL template.</p> -<div class="codehilite"><pre><span class="x"><input type="text" name="email" value="</span><span class="p">$</span><span class="nv">email</span><span class="x">"/></span> +<div class="codehilite"><pre><input type="text" name="email" value="$email"/> </pre></div> @@ -575,26 +575,26 @@ visible. *# This text is outside the com <p>Also, The following statements show examples in which Velocity will throw an exception when attempting to call methods or properties that do not exist. In these examples $bar contains an object that defines a property 'foo' which returns a string, and 'retnull' which returns null.</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">bar</span><span class="p">.</span><span class="nv">bogus</span><span class="x"> </span><span class="cp">##</span><span class="c"> $bar does not provide property bogus, Exception</span><span class="x"></span> -<span class="p">$</span><span class="nv">bar</span><span class="p">.</span><span class="nv">foo</span><span class="p">.</span><span class="nv">bogus</span><span class="x"> </span><span class="cp">##</span><span class="c"> $bar.foo does not provide property bogus, Exception</span><span class="x"></span> -<span class="p">$</span><span class="nv">bar</span><span class="p">.</span><span class="nv">retnull</span><span class="p">.</span><span class="nv">bogus</span><span class="x"> </span><span class="cp">##</span><span class="c"> cannot call a property on null, Exception</pre></span><span class="x"></span> +<div class="codehilite"><pre>$bar.bogus ## $bar does not provide property bogus, Exception +$bar.foo.bogus ## $bar.foo does not provide property bogus, Exception +$bar.retnull.bogus ## cannot call a property on null, Exception</pre> </pre></div> <p>In general strict reference behavior is true for all situations in which references are used except for a special case within the #if directive. If a reference is used within a #if or #elseif directive without any methods or properties, and if it is not being compared to another value, then undefined references are allowed. This behavior provides an easy way to test if a reference is defined before using it in a template. In the following example where $foo is not defined the statements will not throw an exception.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">if</span><span class="p"> ($</span><span class="nv">foo</span><span class="p">)</span><span class="cp">#</span><span class="nf">end</span><span class="x"> </span><span class="cp">##</span><span class="c"> False</span><span class="x"></span> -<span class="cp">#</span><span class="nf">if</span><span class="p"> (</span> <span class="o">!</span> <span class="p">$</span><span class="nv">foo</span><span class="p">)</span><span class="cp">#</span><span class="nf">end</span><span class="x"> </span><span class="cp">##</span><span class="c"> True</span><span class="x"></span> -<span class="cp">#</span><span class="nf">if</span><span class="p"> ($</span><span class="nv">foo</span> <span class="o">&&</span> <span class="p">$</span><span class="nv">foo</span><span class="p">.</span><span class="nv">bar</span><span class="p">)</span><span class="cp">#</span><span class="nf">end</span><span class="x"> </span><span class="cp">##</span><span class="c"> False and $foo.bar will not be evaluated</span><span class="x"></span> -<span class="cp">#</span><span class="nf">if</span><span class="p"> ($</span><span class="nv">foo</span> <span class="o">&&</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">==</span> <span class="s2">"bar"</span><span class="p">)</span><span class="cp">#</span><span class="nf">end</span><span class="x"> </span><span class="cp">##</span><span class="c"> False and $foo == "bar" wil not be evaluated</span><span class="x"></span> -<span class="cp">#</span><span class="nf">if</span><span class="p"> ($</span><span class="nv">foo1</span> <span class="o">||</span> <span class="p">$</span><span class="nv">foo2</span><span class="p">)</span><span class="cp">#</span><span class="nf">end</span><span class="x"> </span><span class="cp">##</span><span class="c"> False $foo1 and $foo2 are not defined</span><span class="x"></span> +<div class="codehilite"><pre>#if ($foo)#end ## False +#if ( ! $foo)#end ## True +#if ($foo && $foo.bar)#end ## False and $foo.bar will not be evaluated +#if ($foo && $foo == "bar")#end ## False and $foo == "bar" wil not be evaluated +#if ($foo1 || $foo2)#end ## False $foo1 and $foo2 are not defined </pre></div> <p>Strict mode requires that comparisons of >, <, >= or <= within an #if directive makes sense. Also, the argument to #foreach must be iterable (this behavior can be modified with the property directive.foreach.skip.invalid). Finally, undefined macro references will also throw an exception in strict mode.</p> <p>References that Velocity attempts to render but evaluate to null will cause an Exception. To simply render nothing in this case the reference can be preceded by '$!' instead of '$', similar to non strict mode. Keep in mind this is different from the reference not existing in the context which will always throw an exception when attempting to render it in strict mode. For example, below $foo has a value of null in the context</p> -<div class="codehilite"><pre><span class="x">this is </span><span class="p">$</span><span class="nv">foo</span><span class="x"> </span><span class="cp">##</span><span class="c"> throws an exception because $foo is null</span><span class="x"></span> -<span class="x">this is </span><span class="p">$</span><span class="x">!foo </span><span class="cp">##</span><span class="c"> renders to "this is " without an exception</span><span class="x"></span> -<span class="x">this is </span><span class="p">$</span><span class="x">!bogus </span><span class="cp">##</span><span class="c"> bogus is not in the context so throws an exception</span><span class="x"></span> +<div class="codehilite"><pre>this is $foo ## throws an exception because $foo is null +this is $!foo ## renders to "this is " without an exception +this is $!bogus ## bogus is not in the context so throws an exception </pre></div> @@ -635,8 +635,8 @@ visible. *# This text is outside the com <h3 id="set">Set<a class="headerlink" href="#set" title="Permanent link">¶</a></h3> <p>The <em>#set</em> directive is used for setting the value of a reference. A value can be assigned to either a variable reference or a property reference, and this occurs in brackets, as demonstrated:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">primate</span> <span class="o">=</span> <span class="s2">"monkey"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">customer</span><span class="p">.</span><span class="nv">Behavior</span> <span class="o">=</span> <span class="p">$</span><span class="nv">primate</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $primate = "monkey" ) +#set( $customer.Behavior = $primate ) </pre></div> @@ -651,32 +651,32 @@ visible. *# This text is outside the com <li>Map</li> </ul> <p>These examples demonstrate each of the aforementioned types:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bill</span> <span class="p">)</span><span class="x"> </span><span class="cp">##</span><span class="c"> variable reference</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span><span class="p">.</span><span class="nv">Friend</span> <span class="o">=</span> <span class="s2">"monica"</span> <span class="p">)</span><span class="x"> </span><span class="cp">##</span><span class="c"> string literal</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span><span class="p">.</span><span class="nv">Blame</span> <span class="o">=</span> <span class="p">$</span><span class="nv">whitehouse</span><span class="p">.</span><span class="nv">Leak</span> <span class="p">)</span><span class="x"> </span><span class="cp">##</span><span class="c"> property reference</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span><span class="p">.</span><span class="nv">Plan</span> <span class="o">=</span> <span class="p">$</span><span class="nv">spindoctor</span><span class="p">.</span><span class="nv">weave</span><span class="p">($</span><span class="nv">web</span><span class="p">)</span> <span class="p">)</span><span class="x"> </span><span class="cp">##</span><span class="c"> method reference</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span><span class="p">.</span><span class="nv">Number</span> <span class="o">=</span> <span class="m">123</span> <span class="p">)</span><span class="x"> </span><span class="cp">##</span><span class="c">number literal</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span><span class="p">.</span><span class="nv">Say</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"Not"</span><span class="p">,</span> <span class="p">$</span><span class="nv">my</span><span class="p">,</span> <span class="s2">"fault"</span><span class="p">]</span> <span class="p">)</span><span class="x"> </span><span class="cp">##</span><span class="c"> ArrayList</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">monkey</span><span class="p">.</span><span class="nv">Map</span> <span class="o">=</span> <span class="p">{</span><span class="s2">"banana"</span> <span class="p">:</span> <span class="s2">"good"</span><span class="p">,</span> <span class="s2">"roast beef"</span> <span class="p">:</span> <span class="s2">"bad"</span><span class="p">})</span><span class="x"> </span><span class="cp">##</span><span class="c"> Map</span><span class="x"></span> +<div class="codehilite"><pre>#set( $monkey = $bill ) ## variable reference +#set( $monkey.Friend = "monica" ) ## string literal +#set( $monkey.Blame = $whitehouse.Leak ) ## property reference +#set( $monkey.Plan = $spindoctor.weave($web) ) ## method reference +#set( $monkey.Number = 123 ) ##number literal +#set( $monkey.Say = ["Not", $my, "fault"] ) ## ArrayList +#set( $monkey.Map = {"banana" : "good", "roast beef" : "bad"}) ## Map </pre></div> <p>NOTE: For the ArrayList example the elements defined with the [..] operator are accessible using the methods defined in the ArrayList class. So, for example, you could access the first element above using $monkey.Say.get(0).</p> <p>Similarly, for the Map example, the elements defined within the { } operator are accessible using the methods defined in the Map class. So, for example, you could access the first element above using $monkey.Map.get("banana") to return a String 'good', or even $monkey.Map.banana to return the same value.</p> <p>The RHS can also be a simple arithmetic expression:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">value</span> <span class="o">=</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">+</span> <span class="m">1</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">value</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">-</span> <span class="m">1</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">value</span> <span class="o">=</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">*</span> <span class="p">$</span><span class="nv">bar</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">value</span> <span class="o">=</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">/</span> <span class="p">$</span><span class="nv">bar</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $value = $foo + 1 ) +#set( $value = $bar - 1 ) +#set( $value = $foo * $bar ) +#set( $value = $foo / $bar ) </pre></div> <p>If the RHS is a property or method reference that evaluates to <em>null</em>, it will <b>not</b> be assigned to the LHS. Depending on how Velocity is configured, it is usually not possible to remove an existing reference from the context via this mechanism. (Note that this can be permitted by changing one of the Velocity configuration properties). This can be confusing for newcomers to Velocity. For example:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="o">=</span> <span class="p">$</span><span class="nv">query</span><span class="p">.</span><span class="nv">criteria</span><span class="p">(</span><span class="s2">"name"</span><span class="p">)</span> <span class="p">)</span><span class="x"></span> -<span class="x">The result of the first query is </span><span class="p">$</span><span class="nv">result</span><span class="x"></span> +<div class="codehilite"><pre>#set( $result = $query.criteria("name") ) +The result of the first query is $result -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="o">=</span> <span class="p">$</span><span class="nv">query</span><span class="p">.</span><span class="nv">criteria</span><span class="p">(</span><span class="s2">"address"</span><span class="p">)</span> <span class="p">)</span><span class="x"></span> -<span class="x">The result of the second query is </span><span class="p">$</span><span class="nv">result</span><span class="x"></span> +#set( $result = $query.criteria("address") ) +The result of the second query is $result </pre></div> @@ -688,44 +688,44 @@ The result of the second query is bill <p>This tends to confuse newcomers who construct <em>#foreach</em> loops that attempt to <em>#set</em> a reference via a property or method reference, then immediately test that reference with an <em>#if</em> directive. For example:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">criteria</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"address"</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $criteria = ["name", "address"] ) -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">criterion</span> <span class="o">in</span> <span class="p">$</span><span class="nv">criteria</span> <span class="p">)</span><span class="x"></span> +#foreach( $criterion in $criteria ) -<span class="x"> </span><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="o">=</span> <span class="p">$</span><span class="nv">query</span><span class="p">.</span><span class="nv">criteria</span><span class="p">($</span><span class="nv">criterion</span><span class="p">)</span> <span class="p">)</span><span class="x"></span> + #set( $result = $query.criteria($criterion) ) -<span class="x"> </span><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="p">)</span><span class="x"></span> -<span class="x"> Query was successful</span> -<span class="x"> </span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> + #if( $result ) + Query was successful + #end -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +#end </pre></div> <p>In the above example, it would not be wise to rely on the evaluation of <em>$result</em> to determine if a query was successful. After <em>$result</em> has been <em>#set</em> (added to the context), it cannot be set back to <em>null</em> (removed from the context). The details of the <em>#if</em> and <em>#foreach</em> directives are covered later in this document.</p> <p>One solution to this would be to pre-set <em>$result</em> to <em>false</em>. Then if the <em>$query.criteria()</em> call fails, you can check.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">criteria</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"name"</span><span class="p">,</span> <span class="s2">"address"</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $criteria = ["name", "address"] ) -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">criterion</span> <span class="o">in</span> <span class="p">$</span><span class="nv">criteria</span> <span class="p">)</span><span class="x"></span> +#foreach( $criterion in $criteria ) -<span class="x"> </span><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="o">=</span> <span class="nf">false</span> <span class="p">)</span><span class="x"></span> -<span class="x"> </span><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="o">=</span> <span class="p">$</span><span class="nv">query</span><span class="p">.</span><span class="nv">criteria</span><span class="p">($</span><span class="nv">criterion</span><span class="p">)</span> <span class="p">)</span><span class="x"></span> + #set( $result = false ) + #set( $result = $query.criteria($criterion) ) -<span class="x"> </span><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">result</span> <span class="p">)</span><span class="x"></span> -<span class="x"> Query was successful</span> -<span class="x"> </span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> + #if( $result ) + Query was successful + #end -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +#end </pre></div> <p>Unlike some of the other Velocity directives, the <em>#set</em> directive does not have an <em>#end</em> statement.</p> <h4 id="literals">Literals<a class="headerlink" href="#literals" title="Permanent link">¶</a></h4> <p>When using the <em>#set</em> directive, string literals that are enclosed in double quote characters will be parsed and rendered, as shown:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">directoryRoot</span> <span class="o">=</span> <span class="s2">"www"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">templateName</span> <span class="o">=</span> <span class="s2">"index.vm"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">template</span> <span class="o">=</span> <span class="s2">"$directoryRoot/$templateName"</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">template</span><span class="x"></span> +<div class="codehilite"><pre>#set( $directoryRoot = "www" ) +#set( $templateName = "index.vm" ) +#set( $template = "$directoryRoot/$templateName" ) +$template </pre></div> @@ -735,33 +735,33 @@ The result of the second query is bill <p>However, when the string literal is enclosed in single quote characters, it will not be parsed:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="s2">"bar"</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">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">blargh</span> <span class="o">=</span> <span class="s1">'$foo'</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">blargh</span><span class="x"></span> +<div class="codehilite"><pre>#set( $foo = "bar" ) +$foo +#set( $blargh = '$foo' ) +$blargh </pre></div> <p>This renders as:</p> -<div class="codehilite"><pre><span class="x">bar</span> -<span class="p">$</span><span class="nv">foo</span><span class="x"></span> +<div class="codehilite"><pre>bar +$foo </pre></div> <p>By default, this feature of using single quotes to render unparsed text is available in Velocity. This default can be changed by editing <code>velocity.properties</code> such that <code>stringliterals.interpolate=false</code>.</p> <p>Alternately, the <em>#[[</em>don't parse me!<em>]]#</em> syntax allows the template designer to easily use large chunks of uninterpreted and unparsed content in VTL code. This can be especially useful in place of <a href="#EscapingVTLDirectives">escaping</a> multiple directives or escaping sections which have content that would otherwise be invalid (and thus unparseable) VTL.</p> -<div class="codehilite"><pre><span class="err">#</span><span class="x">[[</span> -<span class="cp">#</span><span class="nf">foreach</span><span class="p"> ($</span><span class="nv">woogie</span> <span class="o">in</span> <span class="p">$</span><span class="nv">boogie</span><span class="p">)</span><span class="x"></span> -<span class="x"> nothing will happen to </span><span class="p">$</span><span class="nv">woogie</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> -<span class="x">]]</span><span class="err">#</span><span class="x"></span> +<div class="codehilite"><pre>#[[ +#foreach ($woogie in $boogie) + nothing will happen to $woogie +#end +]]# </pre></div> <p>Renders as:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">foreach</span><span class="p"> ($</span><span class="nv">woogie</span> <span class="o">in</span> <span class="p">$</span><span class="nv">boogie</span><span class="p">)</span><span class="x"></span> -<span class="x"> nothing will happen to </span><span class="p">$</span><span class="nv">woogie</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>#foreach ($woogie in $boogie) + nothing will happen to $woogie +#end </pre></div> @@ -785,59 +785,59 @@ The result of the second query is bill <p>Remember that the Velocity context only contains Objects, so when we say 'boolean', it will be represented as a Boolean (the class). This is true even for methods that return <code>boolean</code> - the introspection infrastructure will return a <code>Boolean</code> of the same logical value.</p> <p>The content between the <em>#if</em> and the <em>#end</em> statements become the output if the evaluation is true. In this case, if <em>$foo</em> is true, the output will be: "Velocity!". Conversely, if <em>$foo</em> has a null value, or if it is a boolean false, the statement evaluates as false, and there is no output.</p> <p>An <em>#elseif</em> or <em>#else</em> element can be used with an <em>#if</em> element. Note that the Velocity Templating Engine will stop at the first expression that is found to be true. In the following example, suppose that <em>$foo</em> has a value of 15 and <em>$bar</em> has a value of 6.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o"><</span> <span class="m">10</span> <span class="p">)</span><span class="x"></span> -<span class="x"> **Go North**</span> -<span class="cp">#</span><span class="nf">elseif</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">==</span> <span class="m">10</span> <span class="p">)</span><span class="x"></span> -<span class="x"> **Go East**</span> -<span class="cp">#</span><span class="nf">elseif</span><span class="p">(</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">==</span> <span class="m">6</span> <span class="p">)</span><span class="x"></span> -<span class="x"> **Go South**</span> -<span class="cp">#</span><span class="nf">else</span><span class="x"></span> -<span class="x"> **Go West**</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>#if( $foo < 10 ) + **Go North** +#elseif( $foo == 10 ) + **Go East** +#elseif( $bar == 6 ) + **Go South** +#else + **Go West** +#end </pre></div> <p>In this example, <em>$foo</em> is greater than 10, so the first two comparisons fail. Next <em>$bar</em> is compared to 6, which is true, so the output is <strong>Go South</strong>.</p> <h4 id="relational-and-logical-operators">Relational and Logical Operators<a class="headerlink" href="#relational-and-logical-operators" title="Permanent link">¶</a></h4> <p>Velocity uses the equivalent operator to determine the relationships between variables. Here is a simple example to illustrate how the equivalent operator is used.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p"> ($</span><span class="nv">foo</span> <span class="o">=</span> <span class="s2">"deoxyribonucleic acid"</span><span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p"> ($</span><span class="nv">bar</span> <span class="o">=</span> <span class="s2">"ribonucleic acid"</span><span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set ($foo = "deoxyribonucleic acid") +#set ($bar = "ribonucleic acid") -<span class="cp">#</span><span class="nf">if</span><span class="p"> ($</span><span class="nv">foo</span> <span class="o">==</span> <span class="p">$</span><span class="nv">bar</span><span class="p">)</span><span class="x"></span> -<span class="x"> In this case it's clear they aren't equivalent. So...</span> -<span class="cp">#</span><span class="nf">else</span><span class="x"></span> -<span class="x"> They are not equivalent and this will be the output.</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +#if ($foo == $bar) + In this case it's clear they aren't equivalent. So... +#else + They are not equivalent and this will be the output. +#end </pre></div> <p>Note that the semantics of <em>==</em> are slightly different than Java where <em>==</em> can only be used to test object equality. In Velocity the equivalent operator can be used to directly compare numbers, strings, or objects. When the objects are of different classes, the string representations are obtained by calling <code>toString()</code> for each object and then compared.</p> <p>Velocity has logical AND, OR and NOT operators as well. Below are examples demonstrating the use of the logical AND, OR and NOT operators.</p> -<div class="codehilite"><pre><span class="cp">##</span><span class="c"> logical AND</span><span class="x"></span> +<div class="codehilite"><pre>## logical AND -<span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">&&</span> <span class="p">$</span><span class="nv">bar</span> <span class="p">)</span><span class="x"></span> -<span class="x"> ** This AND that**</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +#if( $foo && $bar ) + ** This AND that** +#end </pre></div> <p>The <em>#if()</em> directive will only evaluate to true if both <em>$foo</em> and <em>$bar</em> are true. If <em>$foo</em> is false, the expression will evaluate to false; <em>$bar</em> will not be evaluated. If <em>$foo</em> is true, the Velocity Templating Engine will then check the value of <em>$bar</em>; if <em>$bar</em> is true, then the entire expression is true and <strong>This AND that</strong> becomes the output. If <em>$bar</em> is false, then there will be no output as the entire expression is false.</p> <p>Logical OR operators work the same way, except only one of the references need evaluate to true in order for the entire expression to be considered true. Consider the following example.</p> -<div class="codehilite"><pre><span class="cp">##</span><span class="c"> logical OR</span><span class="x"></span> +<div class="codehilite"><pre>## logical OR -<span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">||</span> <span class="p">$</span><span class="nv">bar</span> <span class="p">)</span><span class="x"></span> -<span class="x"> **This OR That**</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +#if( $foo || $bar ) + **This OR That** +#end </pre></div> <p>If <em>$foo</em> is true, the Velocity Templating Engine has no need to look at <em>$bar</em>; whether <em>$bar</em> is true or false, the expression will be true, and <strong>This OR That</strong> will be output. If <em>$foo</em> is false, however, <em>$bar</em> must be checked. In this case, if <em>$bar</em> is also false, the expression evaluates to false and there is no output. On the other hand, if <em>$bar</em> is true, then the entire expression is true, and the output is <strong>This OR That</strong></p> <p>With logical NOT operators, there is only one argument :</p> -<div class="codehilite"><pre><span class="cp">##</span><span class="c">logical NOT</span><span class="x"></span> +<div class="codehilite"><pre>##logical NOT -<span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="o">!</span><span class="p">$</span><span class="nv">foo</span> <span class="p">)</span><span class="x"></span> -<span class="x"> **NOT that**</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +#if( !$foo ) + **NOT that** +#end </pre></div> @@ -894,13 +894,13 @@ directive.foreach.maxloops = -1 <p>If you want to stop looping in a foreach from within your template, you can now use the #break directive to stop looping at any time:</p> -<div class="codehilite"><pre><span class="cp">##</span><span class="c"> list first 5 customers only</span><span class="x"></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="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">count</span> <span class="o">></span> <span class="m">5</span> <span class="p">)</span><span class="x"></span> -<span class="x"> </span><span class="cp">#</span><span class="nf">break</span><span class="x"></span> -<span class="x"> </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">end</span><span class="x"></span> +<div class="codehilite"><pre>## list first 5 customers only +#foreach( $customer in $customerList ) + #if( $foreach.count > 5 ) + #break + #end + $customer.Name +#end </pre></div> @@ -916,7 +916,7 @@ directive.foreach.maxloops = -1 <p>The file being included need not be referenced by name; in fact, it is often preferable to use a variable instead of a filename. This could be useful for targeting output according to criteria determined when the page request is submitted. Here is an example showing both a filename and a variable.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">include</span><span class="p">(</span> <span class="s2">"greetings.txt"</span><span class="p">,</span> <span class="p">$</span><span class="nv">seasonalstock</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#include( "greetings.txt", $seasonalstock ) </pre></div> @@ -928,21 +928,21 @@ directive.foreach.maxloops = -1 <p>Like the <em>#include</em> directive, <em>#parse</em> can take a variable rather than a template. Any templates to which <em>#parse</em> refers must be included under TEMPLATE_ROOT. Unlike the <em>#include</em> directive, <em>#parse</em> will only take a single argument.</p> <p>VTL templates can have <em>#parse</em> statements referring to templates that in turn have <em>#parse</em> statements. By default set to 10, the <em>directive.parse.max.depth</em> line of the <code>velocity.properties</code> allows users to customize maximum number of <em>#parse</em> referrals that can occur from a single template. (Note: If the <em>directive.parse.max.depth</em> property is absent from the <code>velocity.properties</code> file, Velocity will set this default to 10.) Recursion is permitted, for example, if the template <code>dofoo.vm</code> contains the following lines:</p> -<div class="codehilite"><pre><span class="x">Count down.</span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">count</span> <span class="o">=</span> <span class="m">8</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">parse</span><span class="p">(</span> <span class="s2">"parsefoo.vm"</span> <span class="p">)</span><span class="x"></span> -<span class="x">All done with dofoo.vm!</span> +<div class="codehilite"><pre>Count down. +#set( $count = 8 ) +#parse( "parsefoo.vm" ) +All done with dofoo.vm! </pre></div> <p>It would reference the template <code>parsefoo.vm</code>, which might contain the following VTL:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">count</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">count</span> <span class="o">=</span> <span class="p">$</span><span class="nv">count</span> <span class="o">-</span> <span class="m">1</span> <span class="p">)</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">count</span> <span class="o">></span> <span class="m">0</span> <span class="p">)</span><span class="x"></span> -<span class="x"> </span><span class="cp">#</span><span class="nf">parse</span><span class="p">(</span> <span class="s2">"parsefoo.vm"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">else</span><span class="x"></span> -<span class="x"> All done with parsefoo.vm!</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>$count +#set( $count = $count - 1 ) +#if( $count > 0 ) + #parse( "parsefoo.vm" ) +#else + All done with parsefoo.vm! +#end </pre></div> @@ -955,20 +955,20 @@ directive.foreach.maxloops = -1 <h3 id="evaluate">Evaluate<a class="headerlink" href="#evaluate" title="Permanent link">¶</a></h3> <p>The <em>#evaluate</em> directive can be used to dynamically evaluate VTL. This allows the template to evaluate a string that is created at render time. Such a string might be used to internationalize the template or to include parts of a template from a database.</p> <p>The example below will display <code>abc</code>.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">source1</span> <span class="o">=</span> <span class="s2">"abc"</span><span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">select</span> <span class="o">=</span> <span class="s2">"1"</span><span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">dynamicsource</span> <span class="o">=</span> <span class="s2">"$source$select"</span><span class="p">)</span><span class="x"></span> -<span class="cp">##</span><span class="c"> $dynamicsource is now the string '$source1'</span><span class="x"></span> -<span class="cp">#</span><span class="nf">evaluate</span><span class="p">($</span><span class="nv">dynamicsource</span><span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set($source1 = "abc") +#set($select = "1") +#set($dynamicsource = "$source$select") +## $dynamicsource is now the string '$source1' +#evaluate($dynamicsource) </pre></div> <h3 id="define">Define<a class="headerlink" href="#define" title="Permanent link">¶</a></h3> <p>The <em>#define</em> directive lets one assign a block of VTL to a reference.</p> <p>The example below will display <code>Hello World!</code>.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">define</span><span class="p">(</span> <span class="p">$</span><span class="nv">block</span> <span class="p">)</span><span class="x">Hello </span><span class="p">$</span><span class="nv">who</span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">who</span> <span class="o">=</span> <span class="s1">'World!'</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">block</span><span class="x"></span> +<div class="codehilite"><pre>#define( $block )Hello $who#end +#set( $who = 'World!' ) +$block </pre></div> @@ -1061,19 +1061,19 @@ directive.foreach.maxloops = -1 <li>boolean value false</li> </ul> <p>When passing references as arguments to Velocimacros, please note that references are passed 'by name'. This means that their value is 'generated' at each use inside the Velocimacro. This feature allows you to pass references with method calls and have the method called at each use. For example, when calling the following Velocimacro as shown</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">macro</span><span class="p">(</span> <span class="nf">callme</span> <span class="p">$</span><span class="nv">a</span> <span class="p">)</span><span class="x"></span> -<span class="x"> </span><span class="p">$</span><span class="nv">a</span><span class="x"> </span><span class="p">$</span><span class="nv">a</span><span class="x"> </span><span class="p">$</span><span class="nv">a</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>#macro( callme $a ) + $a $a $a +#end -<span class="cp">#</span><span class="nf">callme</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span><span class="p">.</span><span class="nv">bar</span><span class="p">()</span> <span class="p">)</span><span class="x"></span> +#callme( $foo.bar() ) </pre></div> <p>results in the method bar() of the reference $foo being called 3 times.</p> <p>At first glance, this feature appears surprising, but when you take into consideration the original motivation behind Velocimacros -- to eliminate cut'n'paste duplication of commonly used VTL -- it makes sense. It allows you to do things like pass stateful objects, such as an object that generates colors in a repeating sequence for coloring table rows, into the Velocimacro.</p> <p>If you need to circumvent this feature, you can always just get the value from the method as a new reference and pass that :</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">myval</span> <span class="o">=</span> <span class="p">$</span><span class="nv">foo</span><span class="p">.</span><span class="nv">bar</span><span class="p">()</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">callme</span><span class="p">(</span> <span class="p">$</span><span class="nv">myval</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $myval = $foo.bar() ) +#callme( $myval ) </pre></div> @@ -1091,59 +1091,59 @@ directive.foreach.maxloops = -1 <p>There is no problem writing "I bought a 4 lb. sack of potatoes at the farmer's market for only $2.50!" As mentioned, a VTL identifier always begins with an upper- or lowercase letter, so $2.50 would not be mistaken for a reference.</p> <h3 id="escaping-valid-vtl-references">Escaping Valid VTL References<a class="headerlink" href="#escaping-valid-vtl-references" title="Permanent link">¶</a></h3> <p>Cases may arise where you do not want to have a reference rendered by Velocity. <em>Escaping</em> special characters is the best way to output VTL's special characters in these situations, and this can be done using the backslash ( ** ) character <i>when those special characters are part of a valid VTL reference</i>.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">email</span> <span class="o">=</span> <span class="s2">"foo"</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>#set( $email = "foo" ) +$email </pre></div> <p>If Velocity encounters a reference in your VTL template to <em>$email</em>, it will search the Context for a corresponding value. Here the output will be <em>foo</em>, because <em>$email</em> is defined. If <em>$email</em> is not defined, the output will be <em>$email</em>.</p> <p>Suppose that <em>$email</em> is defined (for example, if it has the value <em>foo</em>), and that you want to output <em>$email</em>. There are a few ways of doing this, but the simplest is to use the escape character. Here is a demonstration:</p> -<div class="codehilite"><pre><span class="cp">##</span><span class="c"> The following line defines $email in this template:</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">email</span> <span class="o">=</span> <span class="s2">"foo"</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>## The following line defines $email in this template: +#set( $email = "foo" ) +$email +\$email </pre></div> <p>renders as</p> -<div class="codehilite"><pre><span class="x">foo</span> -<span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>foo +$email </pre></div> <p>If, for some reason, you need a backslash before either line above, you can do the following:</p> -<div class="codehilite"><pre><span class="cp">##</span><span class="c"> The following line defines $email in this template:</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">email</span> <span class="o">=</span> <span class="s2">"foo"</span> <span class="p">)</span><span class="x"></span> -<span class="x">\\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\\\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>## The following line defines $email in this template: +#set( $email = "foo" ) +\\$email +\\\$email </pre></div> <p>which renders as</p> -<div class="codehilite"><pre><span class="x">\foo</span> -<span class="x">\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>\foo +\$email </pre></div> <p>Note that the <em>* character bind to the </em>$<em> from the left. The bind-from-left rule causes </em>\\$email<em> to render as </em>\$email<em>. Compare these examples to those in which </em>$email* is not defined.</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\\\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>$email +\$email +\\$email +\\\$email </pre></div> <p>renders as</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> -<span class="x">\\\</span><span class="p">$</span><span class="nv">email</span><span class="x"></span> +<div class="codehilite"><pre>$email +\$email +\\$email +\\\$email </pre></div> <p>Notice Velocity handles references that are defined differently from those that have not been defined. Here is a set directive that gives <em>$foo</em> the value <em>gibbous</em>.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="s2">"gibbous"</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">moon</span><span class="x"> = </span><span class="p">$</span><span class="nv">foo</span><span class="x"></span> +<div class="codehilite"><pre>#set( $foo = "gibbous" ) +$moon = $foo </pre></div> @@ -1180,9 +1180,9 @@ directive.foreach.maxloops = -1 <p>Extra care should be taken when escaping VTL directives that contain multiple script elements in a single directive (such as in an if-else-end statements). Here is a typical VTL if-statement:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">jazz</span> <span class="p">)</span><span class="x"></span> -<span class="x"> Vyacheslav Ganelin</span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>#if( $jazz ) + Vyacheslav Ganelin +#end </pre></div> @@ -1192,9 +1192,9 @@ directive.foreach.maxloops = -1 <p>If <em>$jazz</em> is false, there is no output. Escaping script elements alters the output. Consider the following case:</p> -<div class="codehilite"><pre><span class="x">\</span><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">jazz</span> <span class="p">)</span><span class="x"></span> -<span class="x"> Vyacheslav Ganelin</span> -<span class="x">\</span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>\#if( $jazz ) + Vyacheslav Ganelin +\#end </pre></div> @@ -1206,9 +1206,9 @@ directive.foreach.maxloops = -1 <p>Suppose backslashes precede script elements that are legitimately escaped:</p> -<div class="codehilite"><pre><span class="x">v\\</span><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">jazz</span> <span class="p">)</span><span class="x"></span> -<span class="x"> Vyacheslav Ganelin</span> -<span class="x">\\</span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>v\\#if( $jazz ) + Vyacheslav Ganelin +\\#end </pre></div> @@ -1225,19 +1225,19 @@ directive.foreach.maxloops = -1 <p>Note that things start to break if script elements are not properly escaped.</p> -<div class="codehilite"><pre><span class="x">\\\</span><span class="cp">#</span><span class="nf">if</span><span class="p">(</span> <span class="p">$</span><span class="nv">jazz</span> <span class="p">)</span><span class="x"></span> -<span class="x"> Vyacheslave Ganelin</span> -<span class="x">\\</span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>\\\#if( $jazz ) + Vyacheslave Ganelin +\\#end </pre></div> <p>Here the <em>#if</em> is escaped, but there is an <em>#end</em> remaining; having too many endings will cause a parsing error.</p> <h2 id="vtl-formatting-issues">VTL: Formatting Issues<a class="headerlink" href="#vtl-formatting-issues" title="Permanent link">¶</a></h2> <p>Although VTL in this user guide is often displayed with newlines and whitespaces, the VTL shown below</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">imperial</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"Munetaka"</span><span class="p">,</span><span class="s2">"Koreyasu"</span><span class="p">,</span><span class="s2">"Hisakira"</span><span class="p">,</span><span class="s2">"Morikune"</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">shogun</span> <span class="o">in</span> <span class="p">$</span><span class="nv">imperial</span> <span class="p">)</span><span class="x"></span> -<span class="x"> </span><span class="p">$</span><span class="nv">shogun</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>#set( $imperial = ["Munetaka","Koreyasu","Hisakira","Morikune"] ) +#foreach( $shogun in $imperial ) + $shogun +#end </pre></div> @@ -1247,20 +1247,20 @@ directive.foreach.maxloops = -1 <p>Velocity's default behaviour is to gobble up excess whitespace. The preceding directive can be written as:</p> -<div class="codehilite"><pre><span class="x">Send me</span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"$10 and "</span><span class="p">,</span><span class="s2">"a pie"</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">a</span> <span class="o">in</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">a</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> -<span class="x">please.</span> +<div class="codehilite"><pre>Send me +#set( $foo = ["$10 and ","a pie"] ) +#foreach( $a in $foo ) +$a +#end +please. </pre></div> <p>or as</p> -<div class="codehilite"><pre><span class="x">Send me</span> -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">foo</span> <span class="o">=</span> <span class="o">[</span><span class="s2">"$10 and "</span><span class="p">,</span><span class="s2">"a pie"</span><span class="p">])</span><span class="x"></span> -<span class="x"> </span><span class="cp">#</span><span class="nf">foreach</span><span class="x"> (</span><span class="p">$</span><span class="nv">a</span><span class="x"> in </span><span class="p">$</span><span class="nv">foo</span><span class="x"> )</span><span class="p">$</span><span class="nv">a</span><span class="x"></span> -<span class="x"> </span><span class="cp">#</span><span class="nf">end</span><span class="x"> please.</span> +<div class="codehilite"><pre>Send me +#set($foo = ["$10 and ","a pie"]) + #foreach ($a in $foo )$a + #end please. </pre></div> @@ -1268,15 +1268,15 @@ directive.foreach.maxloops = -1 <h2 id="other-features-and-miscellany">Other Features and Miscellany<a class="headerlink" href="#other-features-and-miscellany" title="Permanent link">¶</a></h2> <h3 id="math">Math<a class="headerlink" href="#math" title="Permanent link">¶</a></h3> <p>Velocity has a handful of built-in mathematical functions that can be used in templates with the <em>set</em> directive. The following equations are examples of addition, subtraction, multiplication and division, respectively:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">+</span> <span class="m">3</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">-</span> <span class="m">4</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">*</span> <span class="m">6</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">/</span> <span class="m">2</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $foo = $bar + 3 ) +#set( $foo = $bar - 4 ) +#set( $foo = $bar * 6 ) +#set( $foo = $bar / 2 ) </pre></div> <p>When a division operation is performed between two integers, the result will be an integer, as the fractional portion is discarded. Any remainder can be obtained by using the modulus (<em>%</em>) operator.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">%</span> <span class="m">5</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $foo = $bar % 5 ) </pre></div> @@ -1287,24 +1287,24 @@ directive.foreach.maxloops = -1 <p>Both <em>n</em> and <em>m</em> must either be or produce integers. Whether <em>m</em> is greater than or less than <em>n</em> will not matter; in this case the range will simply count down. Examples showing the use of the range operator as provided below:</p> -<div class="codehilite"><pre><span class="x">First example:</span> -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">in</span> <span class="o">[</span><span class="m">1</span><span class="o">..</span><span class="m">5</span><span class="p">]</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> +<div class="codehilite"><pre>First example: +#foreach( $foo in [1..5] ) +$foo +#end -<span class="x">Second example:</span> -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">bar</span> <span class="o">in</span> <span class="o">[</span><span class="m">2</span><span class="o">..</span><span class="err">-</span><span class="m">2</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">bar</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +Second example: +#foreach( $bar in [2..-2] ) +$bar +#end -<span class="x">Third example:</span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">arr</span> <span class="o">=</span> <span class="o">[</span><span class="m">0</span><span class="o">..</span><span class="m">1</span><span class="p">]</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">foreach</span><span class="p">(</span> <span class="p">$</span><span class="nv">i</span> <span class="o">in</span> <span class="p">$</span><span class="nv">arr</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="nv">i</span><span class="x"></span> -<span class="cp">#</span><span class="nf">end</span><span class="x"></span> +Third example: +#set( $arr = [0..1] ) +#foreach( $i in $arr ) +$i +#end -<span class="x">Fourth example:</span> -<span class="x">[1..3]</span> +Fourth example: +[1..3] </pre></div> @@ -1327,11 +1327,11 @@ Fourth example: <p>Web page designers concerned with making tables a standard size, but where some will not have enough data to fill the table, will find the range operator particularly useful.</p> <h3 id="advanced-issues-escaping-and">Advanced Issues: Escaping and !<a class="headerlink" href="#advanced-issues-escaping-and" title="Permanent link">¶</a></h3> <p>When a reference is silenced with the <em>!</em> character and the <em>!</em> character preceded by an <em>* escape character, the reference is handled in a special way. Note the differences between regular escaping, and the special case where </em>* precedes <em>!</em> follows it:</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">foo</span> <span class="o">=</span> <span class="s2">"bar"</span> <span class="p">)</span><span class="x"></span> -<span class="p">$</span><span class="x">\!foo</span> -<span class="p">$</span><span class="x">\!</span><span class="err">{</span><span class="x">foo}</span> -<span class="p">$</span><span class="x">\\!foo</span> -<span class="p">$</span><span class="x">\\\!foo</span> +<div class="codehilite"><pre>#set( $foo = "bar" ) +$\!foo +$\!{foo} +$\\!foo +$\\\!foo </pre></div> @@ -1344,18 +1344,18 @@ $\\!foo <p>Contrast this with regular escaping, where <em>* precedes </em>$*:</p> -<div class="codehilite"><pre><span class="x">\</span><span class="p">$</span><span class="nv">foo</span><span class="x"></span> -<span class="x">\</span><span class="p">$</span><span class="x">!foo</span> -<span class="x">\</span><span class="p">$</span><span class="x">!</span><span class="err">{</span><span class="x">foo}</span> -<span class="x">\\</span><span class="p">$</span><span class="x">!</span><span class="err">{</span><span class="x">foo}</span> +<div class="codehilite"><pre>\$foo +\$!foo +\$!{foo} +\\$!{foo} </pre></div> <p>This renders as:</p> -<div class="codehilite"><pre><span class="p">$</span><span class="nv">foo</span><span class="x"></span> -<span class="p">$</span><span class="x">!foo</span> -<span class="p">$</span><span class="x">!</span><span class="err">{</span><span class="x">foo}</span> -<span class="x">\bar</span> +<div class="codehilite"><pre>$foo +$!foo +$!{foo} +\bar </pre></div> @@ -1366,8 +1366,8 @@ $\\!foo <p>Example : <code>#center( #bold("hello") )</code></p> <p>No. A directive isn't a valid argument to a directive, and for most practical purposes, a VM is a directive.</p> <p><em>However...</em>, there are things you can do. One easy solution is to take advantage of the fact that 'doublequote' (") renders its contents. So you could do something like</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">stuff</span> <span class="o">=</span> <span class="s2">"#bold('hello')"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">center</span><span class="p">(</span> <span class="p">$</span><span class="nv">stuff</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set($stuff = "#bold('hello')" ) +#center( $stuff ) </pre></div> @@ -1377,17 +1377,17 @@ $\\!foo <p>Please note that in the latter example the arg is evaluated <i>inside</i> the VM, not at the calling level. In other words, the argument to the VM is passed in in its entirety and evaluated within the VM it was passed into. This allows you to do things like :</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">macro</span><span class="p">(</span> <span class="nf">inner</span> <span class="p">$</span><span class="nv">foo</span> <span class="p">)</span><span class="x"></span> -<span class="x"> inner : </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> +<div class="codehilite"><pre>#macro( inner $foo ) + inner : $foo +#end -<span class="cp">#</span><span class="nf">macro</span><span class="p">(</span> <span class="nf">outer</span> <span class="p">$</span><span class="nv">foo</span> <span class="p">)</span><span class="x"></span> -<span class="x"> </span><span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">bar</span> <span class="o">=</span> <span class="s2">"outerlala"</span><span class="p">)</span><span class="x"></span> -<span class="x"> outer : </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> +#macro( outer $foo ) + #set($bar = "outerlala") + outer : $foo +#end -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">bar</span> <span class="o">=</span> <span class="s1">'calltimelala'</span><span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">outer</span><span class="p">(</span> <span class="s2">"#inner($bar)"</span> <span class="p">)</span><span class="x"></span> +#set($bar = 'calltimelala') +#outer( "#inner($bar)" ) </pre></div> @@ -1408,8 +1408,8 @@ $\\!foo <p>And have rowColor() called repeatedly, rather than just once. To avoid that, invoke the method outside of the VM, and pass the value into the VM.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">color</span> <span class="o">=</span> <span class="p">$</span><span class="nv">bar</span><span class="p">.</span><span class="nv">rowColor</span><span class="p">())</span><span class="x"></span> -<span class="cp">#</span><span class="nf">foo</span><span class="p">(</span> <span class="p">$</span><span class="nv">color</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set($color = $bar.rowColor()) +#foo( $color ) </pre></div> @@ -1441,20 +1441,20 @@ velocimacro.library.autoreload = true <p>A common question that developers ask is <em>How do I do String concatenation? Is there any analogue to the '+' operator in Java?</em>.</p> <p>To do concatenation of references in VTL, you just have to 'put them together'. The context of where you want to put them together does matter, so we will illustrate with some examples.</p> <p>In the regular 'schmoo' of a template (when you are mixing it in with regular content) :</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">size</span> <span class="o">=</span> <span class="s2">"Big"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">name</span> <span class="o">=</span> <span class="s2">"Ben"</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $size = "Big" ) +#set( $name = "Ben" ) -<span class="x">The clock is </span><span class="p">$</span><span class="nv">size</span><span class="p">$</span><span class="nv">name</span><span class="x">.</span> +The clock is $size$name. </pre></div> <p>and the output will render as 'The clock is BigBen'. For more interesting cases, such as when you want to concatenate strings to pass to a method, or to set a new reference, just do</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">size</span> <span class="o">=</span> <span class="s2">"Big"</span> <span class="p">)</span><span class="x"></span> -<span class="cp">#</span><span class="nf">set</span><span class="p">(</span> <span class="p">$</span><span class="nv">name</span> <span class="o">=</span> <span class="s2">"Ben"</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#set( $size = "Big" ) +#set( $name = "Ben" ) -<span class="cp">#</span><span class="nf">set</span><span class="p">($</span><span class="nv">clock</span> <span class="o">=</span> <span class="s2">"$size$name"</span> <span class="p">)</span><span class="x"></span> +#set($clock = "$size$name" ) -<span class="x">The clock is </span><span class="p">$</span><span class="nv">clock</span><span class="x">.</span> +The clock is $clock. </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=1834366&r1=1834365&r2=1834366&view=diff ============================================================================== --- velocity/site/production/engine/devel/vtl-reference.html (original) +++ velocity/site/production/engine/devel/vtl-reference.html Mon Jun 25 18:46:53 2018 @@ -484,12 +484,12 @@ directive.foreach.maxloops = -1 <li><em>[ VM VTL code... ]</em> - Any valid VTL code, anything you can put into a template, can be put into a VM.</li> </ul> <p>Once defined, the VM is used like any other VTL directive in a template.</p> -<div class="codehilite"><pre><span class="cp">#</span><span class="nf">vmname</span><span class="p">(</span> <span class="p">$</span><span class="nv">arg1</span> <span class="p">$</span><span class="nv">arg2</span> <span class="p">)</span><span class="x"></span> +<div class="codehilite"><pre>#vmname( $arg1 $arg2 ) </pre></div> <p><strong>Except</strong>, that when you wish to call a VM with a body, then you must prefix the name of the VM with @. The content of that body may be referenced in the macro definition via $!bodyContent as many or few times as you like.</p> -<div class="codehilite"><pre><span class="err">#</span><span class="x">@vmname( </span><span class="p">$</span><span class="nv">arg1</span><span class="x"> </span><span class="p">$</span><span class="nv">arg2</span><span class="x"> ) here is the body</span><span class="cp">#</span><span class="nf">end</span><span class="x"></span> +<div class="codehilite"><pre>#@vmname( $arg1 $arg2 ) here is the body#end </pre></div> @@ -518,15 +518,15 @@ directive.foreach.maxloops = -1 <h2 id="unparsed-content">Unparsed Content<a class="headerlink" href="#unparsed-content" title="Permanent link">¶</a></h2> <p>Unparsed content is rendered at runtime, but is not parsed or interpreted.</p> <p>Example:</p> -<div class="codehilite"><pre><span class="err">#</span><span class="x">[[</span> +<div class="codehilite"><pre>#[[ -<span class="x">This has invalid syntax that would normally need </span> -<span class="x">"poor man's escaping" like:</span> +This has invalid syntax that would normally need +"poor man's escaping" like: -<span class="x"> - </span><span class="cp">#</span><span class="nf">define</span><span class="p">()</span><span class="x"></span> -<span class="x"> - </span><span class="p">${</span><span class="nv">blah</span><span class="x"></span> + - #define() + - ${blah -<span class="x">]]</span><span class="err">#</span><span class="x"></span> +]]# </pre></div></div></div> <hr/> <div id="copyright">