View Javadoc

1   package org.apache.velocity.runtime.directive;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.    
20   */
21  
22  import java.io.IOException;
23  import java.io.Writer;
24  
25  import org.apache.velocity.context.InternalContextAdapter;
26  import org.apache.velocity.exception.TemplateInitException;
27  import org.apache.velocity.runtime.RuntimeConstants;
28  import org.apache.velocity.runtime.RuntimeServices;
29  import org.apache.velocity.runtime.parser.node.Node;
30  
31  /**
32   * BlockMacro directive is used to invoke Velocity macros with normal parameters and a macro body.
33   * <p>
34   * The macro can then refer to the passed body AST. This directive can be used as a 
35   * "decorator". Body AST can contain any valid Velocity syntax.
36   *
37   * An example:
38   * <pre>
39   * #set($foobar = "yeah!")
40   * 
41   * #macro(strong $txt)
42   * &lt;strong&gt;$bodyContent&lt;/strong&gt; $txt
43   * #end
44   *
45   * #@strong($foobar)
46   * &lt;u&gt;This text is underlined and bold&lt;/u&gt;
47   * #end
48   * </pre>
49   * Will print:
50   * <pre>
51   * &lt;strong&gt;&lt;u&gt;This text is underlined and bold&lt;u&gt;&lt;/strong&gt; yeah!
52   * </pre>
53   * 
54   * bodyContent reference name is configurable (see velocity.properties).
55   *
56   * @author <a href="mailto:wyla@removethis.sci.fi">Jarkko Viinamaki</a>
57   * @since 1.7
58   * @version $Id$
59   */
60  public class BlockMacro extends Block
61  {
62      private String name;
63      private RuntimeMacro macro;
64  
65      public BlockMacro(String name)
66      {
67          this.name = name;
68      }
69      
70      public String getName()
71      {
72          return key;
73      }
74  
75      /**
76       * Override to use the macro name, since it is within an
77       * #@myMacro() ... #end block that the scope in question
78       * would be used.
79       */
80      public String getScopeName()
81      {
82          return name;
83      }
84  
85      /**
86       * Initializes the directive.
87       * 
88       * @param rs
89       * @param context
90       * @param node
91       * @throws TemplateInitException
92       */
93      public void init(RuntimeServices rs, InternalContextAdapter context, Node node)
94          throws TemplateInitException
95      {
96          super.init(rs, context, node);
97          
98          // get name of the reference that refers to AST block passed to block macro call
99          key = rsvc.getString(RuntimeConstants.VM_BODY_REFERENCE, "bodyContent");
100 
101         // use the macro max depth for bodyContent max depth as well
102         maxDepth = rs.getInt(RuntimeConstants.VM_MAX_DEPTH);
103 
104         macro = new RuntimeMacro(name);
105         macro.setLocation(getLine(), getColumn(), getTemplateName());
106         macro.init(rs, context, node);
107     }
108 
109     /**
110      * Renders content using the selected macro and the passed AST body.
111      *
112      * @param context
113      * @param writer
114      * @param node
115      * @return True if the directive rendered successfully.
116      * @throws IOException
117      */
118     public boolean render(InternalContextAdapter context, Writer writer, Node node)
119         throws IOException
120     {
121         return macro.render(context, writer, node, new Reference(context, this));
122     }
123 
124 }