You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@velocity.apache.org by he...@apache.org on 2006/07/09 15:48:24 UTC
svn commit: r420296 -
/jakarta/velocity/docbook/trunk/src/docbook/userguide/VelocityUsersGuide.xml
Author: henning
Date: Sun Jul 9 06:48:24 2006
New Revision: 420296
URL: http://svn.apache.org/viewvc?rev=420296&view=rev
Log:
Finish the References chapter (4)
Start working on the directives chapter (5), 5.1 (set) done
Modified:
jakarta/velocity/docbook/trunk/src/docbook/userguide/VelocityUsersGuide.xml
Modified: jakarta/velocity/docbook/trunk/src/docbook/userguide/VelocityUsersGuide.xml
URL: http://svn.apache.org/viewvc/jakarta/velocity/docbook/trunk/src/docbook/userguide/VelocityUsersGuide.xml?rev=420296&r1=420295&r2=420296&view=diff
==============================================================================
--- jakarta/velocity/docbook/trunk/src/docbook/userguide/VelocityUsersGuide.xml (original)
+++ jakarta/velocity/docbook/trunk/src/docbook/userguide/VelocityUsersGuide.xml Sun Jul 9 06:48:24 2006
@@ -565,9 +565,9 @@
<para>Using <link linkend="chapter-velocity-macros">Velocity
Macros</link>, the behaviour of escaping <literal>#</literal> changes a
- bit:<note>
- <para>And you probably thought, the worst part was over...</para>
- </note></para>
+ bit:<footnote>
+ <para>...and you probably thought, the worst part was over...</para>
+ </footnote></para>
<example id="example-escaping-macros">
<title>Escaping Macros</title>
@@ -597,10 +597,10 @@
<para>There are three types of references in the VTL:
<firstterm>variables</firstterm>, <firstterm>properties</firstterm> and
<firstterm>methods</firstterm>. They are the glue that connects the
- business logic of your application, which probably is written in Java to
- your templates. The Java code and the templates must use the same set of
- references, so you, as a template designer and your engineer must agree on
- the references available for use on the templates.</para>
+ business logic of your application written in Java to your templates. The
+ Java code and the templates must use the same set of references, so you,
+ as a template designer and the developers writing the application logic
+ must agree on the references available for use on the templates.</para>
<para>Every reference that is output when a template is rendered, is
converted to a Java string by calling the <literal>toString()</literal>
@@ -757,8 +757,8 @@
</note>
<para>If you wonder about setting property values, please look up the
- #set() directive chapter. The setting of properties is discussed
- there.</para>
+ <literal>#set()</literal> directive chapter. The setting of properties
+ is discussed there.</para>
<section id="section-property-lookup-rules">
<title>Default property lookup rules</title>
@@ -813,8 +813,8 @@
<para>There are some exotic naming cases, such as a property
starting with multiple upper-case letters which are treated
specially according to the Java Bean specification. Velocity does
- not conform to this specification, so if you have a method called
- <literal>getURL()</literal>, you cannot use
+ not conform to this specification to the last letter, so if you have
+ a method called <literal>getURL()</literal>, you cannot use
<literal>$obj.url</literal> to invoke the method, you must use
<literal>$obj.URL</literal> or <literal>$obj.uRL</literal>. This
might change in future versions of Velocity.</para>
@@ -881,10 +881,10 @@
</example>
<warning>
- <para>The last #set() example will not work in Velocity versions
- before 1.5 unless the <literal>$album</literal> object implements
- <literal>java.util.Map</literal>. This is a bug in older Velocity
- versions.</para>
+ <para>The last <literal>#set()</literal> example will not work in
+ Velocity versions before 1.5 unless the <literal>$album</literal>
+ object implements <literal>java.util.Map</literal>. This is a bug in
+ older Velocity versions.</para>
</warning>
<para>Not every method invocation can be replaced by short hand
@@ -903,140 +903,88 @@
$shop.orderFruits()
## Can't pass a parameter list
-$book.setAuthorandTitle("George Orwell", "Homage to Catalonia")</programlisting>
+$book.setAuthorAndTitle("George Orwell", "Homage to Catalonia")</programlisting>
</example>
</section>
- <section id="section-formal-reference-notation">
- <title>Formal Reference Notation</title>
+ <section id="section-reference-miscelany">
+ <title>Reference Miscellany</title>
+
+ <section id="section-formal-reference-notation">
+ <title>Separating Identifiers and template text</title>
+
+ <para>When writing templates, you might encounter situations in which
+ it is necessary to explicitly separate a reference from the
+ surrounding template text. In the examples above, this was done
+ implicitly through whitespace. Additionally there is a formal notation
+ which wraps the identifiers with curly braces:</para>
- <para>Shorthand notation for references was used for the examples listed
- above, but there is also a formal notation for references, which is
- demonstrated below:</para>
+ <example>
+ <title>Formal notation for Velocity references</title>
- <programlisting>${fruit}
+ <programlisting>${fruit}
${customer.address}
${purchase.getTotal()}</programlisting>
+ </example>
- <para>In almost all cases you will use the shorthand notation for
- references, but in some cases the formal notation is required for
- correct processing.</para>
-
- <para>Suppose you were building an extension to your fruit shop where
- juices are sold. <literal>$fruit</literal> contains the name of the
- juice which should be sold. Using the shorthand notation would be
- inadequate for this task. Consider the following example:</para>
-
- <programlisting>You have selected $fruitjuice.</programlisting>
-
- <para>There is ambiguity here, and Velocity assumes that
- <literal>$fruitjuice</literal>, not <literal>$fruit</literal>, is the
- identifier that you want to use. Finding no value for
- <literal>$fruitjuice</literal>, it will return
- <literal>$fruitjuice</literal>. Using formal notation can resolve this
- problem.</para>
-
- <programlisting>You have selected ${fruit}juice.</programlisting>
-
- <para>Now Velocity knows that <literal>$fruit</literal>, not
- <literal>$fruitjuice</literal>, is the reference. Formal notation is
- often useful when references are directly adjacent to text in a
- template.</para>
- </section>
+ <para>Suppose you were building an extension to your fruit shop where
+ juices are sold. <literal>$fruit</literal> contains the name of the
+ juice which should be sold. Using the shorthand notation would be
+ inadequate for this task. Consider the following example:</para>
+
+ <programlisting>You have selected $fruitjuice.</programlisting>
+
+ <para>There is ambiguity here, and Velocity assumes that
+ <literal>$fruitjuice</literal>, not <literal>$fruit</literal>, is the
+ identifier that you want to use. Finding no value for
+ <literal>$fruitjuice</literal>, it will return
+ <literal>$fruitjuice</literal>. Using formal notation can resolve this
+ problem.</para>
+
+ <programlisting>You have selected ${fruit}juice.</programlisting>
+
+ <para>Now Velocity knows that <literal>$fruit</literal>, not
+ <literal>$fruitjuice</literal>, is the reference. Formal notation is
+ often useful when references are directly adjacent to text in a
+ template.</para>
+ </section>
- <section id="section-quiet-reference-notation">
- <title>Quiet reference notation</title>
+ <section id="section-quiet-reference-notation">
+ <title>Quiet reference notation</title>
- <para>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.</para>
-
- <programlisting><input type="text" name="email" value="$email"/></programlisting>
-
- <para>When the form initially loads, the variable reference
- <literal>$email</literal> has no value, but you prefer a blank text
- field to one with a value of "$email". Using the quiet reference
- notation circumvents Velocity's normal behavior; instead of using
- <literal>$email</literal> in the VTL you would use
- <literal>$!email</literal>. So the above example would look like the
- following:</para>
-
- <programlisting><input type="text" name="email" value="$!email"/></programlisting>
-
- <para>Now when the form is initially loaded and
- <literal>$email</literal> still has no value, an empty string will be
- output instead of <literal>$email</literal>.</para>
-
- <para>Formal and quiet reference notation can be used together, as
- demonstrated below.</para>
-
- <programlisting><input type="text" name="email" value="$!{email}"/></programlisting>
-
- <caution>
- <para>It is very easy to confuse the quiet reference notation with the
- boolean <emphasis>not</emphasis>-Operator. Using the not-Operator, you
- use <literal>!${foo}</literal>, while the quiet reference notation is
- <literal>$!{foo}</literal>. And yes, you will end up sometimes with
- <literal>!$!{foo}</literal>...</para>
- </caution>
- </section>
- </chapter>
+ <para>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.</para>
- <chapter id="chapter-getting-literal">
- <title>Getting literal</title>
+ <programlisting><input type="text" name="email" value="$email"/></programlisting>
- <para>VTL uses special characters, such as <literal>$</literal> and
- <literal>#</literal>, to do its work, so some added care should be taken
- where using these characters in your templates. This chapter deals with
- escaping the <literal>$</literal> character.</para>
- </chapter>
+ <para>When the form initially loads, the variable reference
+ <literal>$email</literal> has no value, but you probably prefer a
+ blank text field to one with a value of <emphasis>$email</emphasis>.
+ Using the quiet reference notation circumvents Velocity's normal
+ behavior; instead of using <literal>$email</literal> in the VTL you
+ would use <literal>$!email</literal>. So the above example would look
+ like the following:</para>
+
+ <programlisting><input type="text" name="email" value="$!email"/></programlisting>
+
+ <para>Now when the form is initially loaded and
+ <literal>$email</literal> still has no value, an empty string will be
+ output instead of <literal>$email</literal>.</para>
+
+ <para>Formal and quiet reference notation can be used together:</para>
- <chapter id="chapter-case-substitution">
- <title>Case Substitution</title>
+ <programlisting><input type="text" name="email" value="$!{email}"/></programlisting>
- <para>Now that you are familiar with references, you can begin to apply
- them effectively in your templates. Velocity references take advantage of
- some Java principles that template designers will find easy to use. For
- example:</para>
-
- <programlisting>$foo
-
-$foo.getBar()
-## is the same as $foo.bar and $foo.Bar
-
-$data.setUser("jon")
-## is the same as
-#set( $data.User = "jon" )
-
-$data.getRequest().getServerName()
-## is the same as
-$data.request.serverName and $data.Request.ServerName
-## and also
-${data.Request.ServerName}</programlisting>
-
- <para>These examples illustrate alternative uses for the same references.
- Velocity takes advantage of Java's introspection and bean features to
- resolve the reference names to both objects in the Context as well as the
- objects methods. It is possible to embed and evaluate references almost
- anywhere in your template.</para>
-
- <para>Velocity, which is modelled loosely after the Bean specifications
- defined by Sun Microsystems, is case sensitive; however, its developers
- have strove to catch and correct user errors wherever possible. When the
- method <literal>getFoo()</literal> is referred to in a template by
- <literal>$bar.foo</literal>, Velocity will first try
- <literal>$getfoo</literal>. If this fails, it will then try
- <literal>$getFoo</literal>. Similarly, when a template refers to
- <literal>$bar.Foo</literal>, Velocity will try
- <literal>$getFoo()</literal> first and then try
- <literal>getfoo()</literal>.</para>
-
- <para>Note: <emphasis>References to instance variables in a template are
- not resolved.</emphasis> Only references to the attribute equivalents of
- JavaBean getter/setter methods are resolved (i.e.
- <literal>$foo.Name</literal> does resolve to the class Foo's
- <literal>getName()</literal> instance method, but not to a public
- <literal>Name</literal> instance variable of Foo).</para>
+ <caution>
+ <para>It is very easy to confuse the quiet reference notation with
+ the boolean <emphasis>not</emphasis>-Operator. Using the
+ not-Operator, you use <literal>!${foo}</literal>, while the quiet
+ reference notation is <literal>$!{foo}</literal>. And yes, you will
+ end up sometimes with <literal>!$!{foo}</literal>...</para>
+ </caution>
+ </section>
+ </section>
</chapter>
<chapter id="chapter-directives">
@@ -1045,32 +993,31 @@
<para>References allow template designers to generate dynamic content for
web sites, while <emphasis>Directives</emphasis> permit web designers to
truly take charge of the appearance and content of the web site. A
- directive is a script elements that can be used to manipulate the
- rendering of the template.</para>
+ directive is a script element that can be used to manipulate the rendering
+ of the template.</para>
- <para>Directives always begin with a <literal>#</literal>. Like
- references, the name of the directive may be bracketed by a
- <literal>{</literal> and a <literal>}</literal> symbol. This is useful
- with directives that are immediately followed by text. For example the
- following produces an error:</para>
+ <para>As described in Chapter 3.1, Velocity Directives are part of either
+ single or multi-line statements.</para>
- <programlisting>#if($a==1)true enough#elseno way!#end</programlisting>
+ <section id="section-the-set-directive">
+ <title>The <firstterm>set</firstterm> directive</title>
- <para>In such a case, use the curly braces to separate
- <literal>#else</literal> from the rest of the line.</para>
+ <para>The <literal>set</literal> directive is used for setting the value
+ of a reference. It is used in a single-line statement.</para>
- <programlisting>#if($a==1)true enough#{else}no way!#end</programlisting>
+ <para>A value can be assigned to either a variable reference or a
+ property reference.</para>
- <section id="section-the-set-directive">
- <title>The #set directive</title>
+ <example>
+ <title>Value assignment using the <emphasis>set</emphasis>
+ directive</title>
- <para>The <literal>#set</literal> 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:</para>
+ <programlisting>## Assigning a variable value
+#set( $fruit = "apple" )
- <programlisting>#set( $fruit = "apple" )
+## Assigning a property value
#set( $customer.Favourite = $fruit )</programlisting>
+ </example>
<para>The left hand side (LHS) of the assignment must be a variable
reference or a property reference. The right hand side (RHS) can be one
@@ -1104,70 +1051,129 @@
<listitem>
<para>Map</para>
</listitem>
+
+ <listitem>
+ <para>Expression</para>
+ </listitem>
</itemizedlist></para>
- <para>These examples demonstrate each of the aforementioned
- types:</para>
+ <example>
+ <title>Valid reference assignments</title>
+
+ <programlisting>## variable reference
+#set( $fruit = $selectedFruit )
+
+## string literal
+#set( $fruit.flavor = "sweet" )
+
+## property reference
+#set( $fruit.amount = $cart.total )
+
+## method reference
+#set( $fruit.color = $colorlist.selectColor($select) )
+
+## number literal
+#set( $fruit.value = 123 )
- <programlisting>#set( $fruit = $selectedFruit ) ## variable reference
-#set( $fruit.flavor = "sweet" ) ## string literal
-#set( $fruit.amount = $cart.total ) ## property reference
-#set( $fruit.color = $colorlist.select($select) ) ## method reference
-#set( $fruit.value = 123 ) ## number literal
-#set( $fruit.sorts = ["Apple", "Pear", "Orange"] ) ## List
-#set( $fruit.shapes = {"Apple" : "round", "Pear" : "conical"}) ## Map</programlisting>
-
- <para>NOTE: For the List example the elements defined with the
- <literal>[..]</literal> operator are accessible using the methods
- defined in the <literal>java.util.List</literal> class. So, for example,
- you could access the first element above using
- <literal>$fruit.sorts.get(0)</literal>.</para>
-
- <para>Similarly, for the Map example, the elements defined within the
- <literal>{..}</literal> operator are accessible using the methods
- defined in the <literal>java.util.Map</literal> class. So, for example,
- you could access the first element above using
- <literal>$fruit.shapes.get("Granny")</literal> to return the String
- <literal>round</literal>, or even
- <literal>$fruit.shapes.Granny</literal> to return the same value.</para>
+## List
+#set( $fruit.sorts = ["Apple", "Pear", "Orange"] )
+
+## Map
+#set( $fruit.shapes = {"Apple" : "round", "Pear" : "conical"}) </programlisting>
+ </example>
+
+ <note>
+ <para>For the List example the elements defined with the
+ <literal>[..]</literal> operator are accessible using the methods
+ defined in the <literal>java.util.List</literal> class. So, for
+ example, you could access the first element above using
+ <literal>$fruit.sorts.get(0)</literal>.</para>
+
+ <para>Similarly, for the Map example, the elements defined within the
+ <literal>{..}</literal> operator are accessible using the methods
+ defined in the <literal>java.util.Map</literal> class. So, for
+ example, you could access the first element above using
+ <literal>$fruit.shapes.get("Apple")</literal> to return the String
+ <literal>round</literal>, or even
+ <literal>$fruit.shapes.Apple</literal> to return the same
+ value.</para>
+ </note>
- <para>The RHS can also be a simple arithmetic expression:</para>
+ <para>The RHS can also be an arithmetic expression as described in the
+ Math chapter below.</para>
- <programlisting>#set( $value = $foo + 1 )
+ <example>
+ <title>Expression examples</title>
+
+ <programlisting>#set( $value = $foo + 1 )
#set( $value = $bar - 1 )
#set( $value = $foo * $bar )
#set( $value = $foo / $bar )</programlisting>
+ </example>
+
+ <section id="section-assigning-null-values">
+ <title>Assigning null values to references</title>
+
+ <para>In its default configuration, Velocity treats
+ <literal>null</literal> values on the RHS special. If your developers
+ don't change the default configuration, you must understand that it is
+ not possible to assign a null value through a <literal>set</literal>
+ directive to a reference. Starting with Velocity 1.5, a runtime
+ property (<literal>directive.set.null.allowed</literal>) exists that
+ removes this restriction. If you don't want <literal>null</literal>
+ values to be treated special, tell your application developers that
+ they should look up this property in the <emphasis>Velocity Developers
+ Guide</emphasis> and set it to true.</para>
+
+ <note>
+ <para>Removing this restriction is one of the new features of
+ Velocity 1.5. If you are maintaining existing template code from
+ older Velocity versions, you probably want to keep the old
+ behaviour.</para>
+
+ <para>For new developments based on Velocity 1.5 and beyond, we
+ strongly recommend that you don't treat null values on the RHS
+ special (set <literal>directive.set.null.allowed</literal> to be
+ true). This will be the default behaviour in future Velocity
+ versions.</para>
+ </note>
+
+ <para>The remainder of this chapter assumes that you kept the default
+ configuration of Velocity.</para>
+
+ <para>If the RHS is a property or method reference that evaluates to
+ <literal>null</literal>, it will <emphasis>not</emphasis> be assigned
+ to the LHS and the LHS <emphasis>will not be altered</emphasis>. This
+ is very different from the behaviour in e.g. the Java programming
+ language and needs some discussion.</para>
- <para>If the RHS is a property or method reference that evaluates to
- <literal>null</literal>, it will <emphasis>not</emphasis> 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 a configuration
- property). This can be confusing for newcomers to Velocity. For
- example:</para>
+ <para>In the following example, two queries are executed using the
+ same set of template references:</para>
- <programlisting>#set( $result = $query.criteria("fruit") )
+ <programlisting>#set( $result = $query.criteria("fruit") )
The result of the first query is $result
#set( $result = $query.criteria("customer") )
The result of the second query is $result</programlisting>
- <para>If <literal>$query.criteria("name")</literal> returns the string
- "apple", and <literal>$query.criteria("customer")</literal> returns
- <literal>null</literal>, the above VTL will render as the
- following:</para>
+ <para>If <literal>$query.criteria("name")</literal> returns the string
+ "apple", and <literal>$query.criteria("customer")</literal> returns
+ null, the above VTL will render as the following:</para>
- <programlisting>The result of the first query is apple
+ <programlisting>The result of the first query is apple
The result of the second query is apple</programlisting>
- <para>Unfortunately, this can lead to hard-to-detect errors, for example
- with <literal>#foreach</literal> loops that attempt to
- <literal>#set</literal> a reference via a property or method reference,
- then immediately test that reference with an <literal>#if</literal>
- directive:</para>
+ <para>In the second <literal>set</literal> directive, the RHS is null,
+ because <literal>$query.criteria("customer")</literal> returned null.
+ So the RHS will not be modified (and the old value retained). </para>
+
+ <para>Unfortunately, this can lead to hard-to-detect errors, for
+ example with <literal>#foreach</literal> loops that attempt to change
+ a reference using a <literal>set</literal> directive, then immediately
+ test that reference with an <literal>if</literal> directive:</para>
- <programlisting>#set( $criteria = ["fruit", "customer"] )
+ <programlisting>#set( $criteria = ["fruit", "customer"] )
#foreach( $criterion in $criteria )
@@ -1179,35 +1185,32 @@
#end</programlisting>
- <para>In the above example, it would not be wise to rely on the
- evaluation of <literal>$result</literal> to determine if a query was
- successful. After <literal>$result</literal> has been
- <literal>#set</literal> (added to the context), it cannot be set back to
- <literal>null</literal> (removed from the context). The details of the
- <literal>#if</literal> and <literal>#foreach</literal> directives are
- covered later in this document.</para>
-
- <para>One solution to this would be to pre-set
- <literal>$result</literal> to <literal>false</literal>. Then if the
- <literal>$query.criteria()</literal> call fails, you can check.</para>
+ <para>In the above example, it would not be wise to rely on the
+ evaluation of <literal>$result</literal> to determine if a query was
+ successful. After <literal>$result</literal> has been set (added to
+ the context), it cannot be set back to null (removed from the
+ context).</para>
- <programlisting>#set( $criteria = ["name", "address"] )
+ <para>One solution to this would be to reset the value of
+ <literal>$result</literal> in every loop iteration:</para>
+
+ <programlisting>#set( $criteria = ["name", "address"] )
#foreach( $criterion in $criteria )
- #set( $result = false )
+ #set( $result = "" )
#set( $result = $query.criteria($criterion) )
- #if( $result )
+ #if( $result != "" )
Query was successful
#end
#end</programlisting>
- <para>However, the easiest way is to use the quiet reference
- notation:</para>
+ <para>However, the easiest way is to use the quiet reference
+ notation:</para>
- <programlisting>#set( $criteria = ["name", "address"] )
+ <programlisting>#set( $criteria = ["name", "address"] )
#foreach( $criterion in $criteria )
@@ -1219,13 +1222,9 @@
#end</programlisting>
- <para>If the query fails, <literal>$result</literal> gets the empty
- string assigned. In an <literal>#if</literal> directive, the empty
- string evaluates to <emphasis>false</emphasis>.</para>
-
- <para>Unlike some of the other Velocity directives, the
- <literal>#set</literal> directive does not have an
- <literal>#end</literal> statement.</para>
+ <para>If the query fails, <literal>$result</literal> gets the empty
+ string assigned.</para>
+ </section>
<section id="section-string-literals">
<title>String Literals</title>
@@ -1254,13 +1253,15 @@
<para>This renders as:</para>
- <programlisting>apple $fruit</programlisting>
+ <programlisting>apple
+
+$fruit</programlisting>
<para>By default, rendering unparsed text using single quotes is
activated in Velocity. This default can be changed by changing the
- <literal>stringliterals.interpolate</literal> to read
- <literal>false</literal> (The Developers Guide contains information on
- how to do this).</para>
+ <literal>runtime.interpolate.string.literals</literal> property to be
+ false. (See the <emphasis>Velocity Developers Guide</emphasis> for
+ more information).</para>
</section>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: velocity-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: velocity-dev-help@jakarta.apache.org