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>&lt;input type="text" name="email" value="$email"/&gt;</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>&lt;input type="text" name="email" value="$!email"/&gt;</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>&lt;input type="text" name="email" value="$!{email}"/&gt;</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>&lt;input type="text" name="email" value="$email"/&gt;</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>&lt;input type="text" name="email" value="$!email"/&gt;</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>&lt;input type="text" name="email" value="$!{email}"/&gt;</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