WE05 Hacking Velocity
Total Page:16
File Type:pdf, Size:1020Kb
Hacking Velocity – ApacheCon 2004 • What is Velocity • Velocity Tools • Custom Directives • Custom Resourceloaders • Custom Introspector • Adding Event Handlers • Modifying Velocity Syntax Presenter Contact Info: Will Glass-Husain Menlo Park, California USA [email protected] + 1 415 440-7500 November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 1 What is Velocity? • A templating engine that can generate any type of text output, including HTML, email, SQL, or Java source code. • Based on a "pull" approach in which a text file includes "References" to data objects that are pulled from a provided "Context". $Date Date Order Dear $Contact.FirstName $Contact.LastName, Contact Thank you for your recent purchase of $Order.ProductName. The cost of the item was $Order.TotalCost#if($Order.Tax > 0) including a tax of $Order.TaxRate%#end. Sincerely, November 17, 2004 Biggest and Best Book Merchants, Inc. Dear Jennifer Glass, Thank you for your recent purchase of Alice in Wonderland, Annotated Edition. The cost of the item was $29.95. Sincerely, Biggest and Best Book Merchants, Inc. November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 2 Basic Velocity Concepts • References – References objects from the Velocity context. Starts with a "$". – Can have Properties or Methods – Common practice is to provide two types: data objects (with properties) and "tools" (with methods). – Examples: • $contact.FirstName • $format("$#,##0.00",$order.price) • Directives – Control statements. Starts with a "#" – Example block directive: • #if ($columncount > 0) display a table #end – Example line directive: • #include('header.vm') November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 3 How To Use Velocity Load a Template From a File VelocityEngine ve = new VelocityEngine(); ve.setProperty("file.resource.loader.path","templates"); ve.init(); Context c = new VelocityContext(); c.add("order",order); c.add("contact",contact); Template t1 = ve.getTemplate("inputfile.vm"); StringWriter writer = new StringWriter(); t1.merge(c,writer); String result = writer.toString(); Evaluate a Template stored as a String VelocityEngine ve = new VelocityEngine(); ve.init(); Context c = new VelocityContext(). c.add("order",order); c.add("contact",contact); StringWriter writer = new StringWriter(); ve.evaluate(c,writer,"velocity",inputstring); String result = writer.toString() November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 4 Improve Productivity with Velocity-Tools from the web site: http://jakarta.apache.org/velocity/tools/index.html VelocityTools is a collection of Velocity subprojects with a common goal of creating tools and infrastructure for building both web and non-web applications using the Velocity template engine. • GenericTools – GenericTools is a group of reuseable and documented tools that can be added to a Velocity context. A tool is simply a class which can perform various tasks when made available to the Velocity engine. Most tools are optimized for use with an automatically managed toolbox (see VelocityViewServlet). • VelocityView – VelocityView contains a standalone servlet (VelocityViewServlet) which can render templates for web applications. – Also included is a Toolbox Manager which can automatically make "view tools" and data available to the templates. Any class with public methods can be used as a tool in the template. – VelocityLayoutServlet is an extension of the basic VelocityViewServlet that can render screen content into common layout templates. • VelocityStruts – VelocityStruts is a set of tools for using the Velocity template engine as the view layer for a web application built upon the Jakarta Struts framework. – This work leverages the VelocityViewServlet and additional tools which make it easy to integrate the Velocity with Struts. Several example hybrid applications are included. November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 5 Example Tools Generic Tools VelocityView (web) Tools • DateTool • AbstractSearchTool • IteratorTool • CookieTool • MathTool • ImportTool • NumberTool • LinkTool • RenderTool • ParameterParser • ViewRenderTool Using a Tool Context c = new VelocityContext(); c.add("date",new DateTool()); Template t1 = ve.getTemplate("inputfile.vm"); StringWriter writer = new StringWriter(); t1.merge(c,writer); String result = writer.toString(); November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 6 VelocityViewServlet: Serve Velocity Pages Over the Web • Quick and easy way to build a web app. • Serves Velocity pages just like HTM or JSP files. • Tools are automatically placed in the Velocity context according to "toolbox.xml" config file. Excerpt: <tool> <key>math</key> <scope>application</scope> <class>org.apache.velocity.tools.generic.MathTool</class> </tool> • Any tool that has a scope of session or request is passed session and/or request info when it is initialized. (if the tool implements ViewContext). • VelocityViewServlet can be subclassed to add additional functionality. Example (in distribution): VelocityLayoutServlet, which uses a 2 pass render in order to apply a common layout to all web pages. Note: VelocityViewServlet replaces deprecated VelocityServlet distributed with Velocity project November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 7 VelocityViewServlet: Configuration Example (web.xml) WEB-INF/web.xml <?xml version="1.0" encoding="ISO-8859-1"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Example application</display-name> <!-- Define Velocity template compiler --> <servlet> <servlet-name>velocity</servlet-name> <servlet-class>org.apache.velocity.tools.view.servlet.VelocityViewServlet </servlet-class> <init-param> <param-name>org.apache.velocity.toolbox</param-name> <param-value>/WEB-INF/toolbox.xml</param-value> </init-param> <init-param> <param-name>org.apache.velocity.properties</param-name> <param-value>/WEB-INF/velocity.properties</param-value> </init-param> </servlet> <!-- Map *.vm files to Velocity --> <servlet-mapping> <servlet-name>velocity</servlet-name> <url-pattern>*.vm</url-pattern> </servlet-mapping> </web-app> November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 8 VelocityViewServlet: Configuration Example (toolbox.xml) WEB-INF/toolbox.xml <?xml version="1.0"?> <toolbox> <tool> <key>date</key> <scope>application</scope> <class>org.apache.velocity.tools.generic.DateTool</class> </tool> <tool> <key>params</key> <scope>request</scope> <class>org.apache.velocity.tools.view.tools.ParameterParser</class> </tool> <tool> <key>cookie</key> <scope>request</scope> <class>org.apache.velocity.tools.view.tools.CookieTool</class> </tool> <data type="number"> <key>app_version</key> <value>1.5</value> </data> <data type="string"> <key>app_name</key> <value>A Carroll Compendium</value> </data> </toolbox> November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 9 VelocityViewServlet: Configuration Example (velocity.properties) WEB-INF/velocity.properties # all optional velocimacro.library = /WEB-INF/VM_global_library.vm velocimacro.permissions.allow.inline = true velocimacro.permissions.allow.inline.to.replace.global = false velocimacro.permissions.allow.inline.local.scope = false velocimacro.context.localscope = false November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 10 VelocityViewStruts: An Alternative To JSP VelocityStruts Tools • ActionMessagesTool • StrutsLinkTool • ErrorsTool • SecureLinkTool • FormTool • TilesTool • MessageTool • ValidatorTool November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 11 Controlling Velocity Template Generation with a Custom Directive • Consider – can the problem you are trying to solve be done more simply with a Tool or VelocityMacro? • If not, Velocity allows you to code your own custom directives by doing the following: – Create a class that extends org.apache.velocity.runtime.directive.Directive – Add the following to velocity.properties userdirective = yourdirectiveclass • Review the directives in the velocity source code for good examples. For example, review org.apache.velocity.runtime.directive.ForEach November 17, 2004 (c) 2004 Will Glass-Husain. Non-commercial redistribution permitted freely. 12 Custom Directive Example: Generate Endnotes Usage: #endNotes All in the golden afternoon (*1:In these prefatory verses Carroll recalls that "golden afternoon" in 1862 when he and his friend the Reverend Robinson Duckworth (then a fellow of Trinity College, Oxford, later canon of Westminster) took the three charming Liddell sisters on a rowing expedition up the Thames. *) Full leisurely we glide; For both our oars, with little skill, By little arms are plied, While little hands make vain pretence Our wanderings to guide. (* 2:Note how this stanza puns three times with the word "little." "Liddle" was pronounced to rhyme with "fiddle." *) #end Results: All in the golden afternoon Full leisurely we glide; For both our oars, with little skill, By little arms are plied, While little hands make vain pretence Our wanderings to guide. NOTES 1: In these prefatory verses Carroll recalls that "golden afternoon" in 1862 when he and his friend