SlideShare a Scribd company logo
Apache Velocity A Java Template Engine Nathan Bubna [email_address] , Henning P. Schmiedehausen [email_address] OSCON 2007, July 25th 2007  Portland, Oregon http://people.apache.org/~nbubna/oscon2007(.zip)
Template Engine? Defines a simple language (VTL – Velocity Template Language) Templates are text containing active elements Active elements are replaced with values from the model No “industry standard” template language Templates are processed, not compiled
Velocity Background Velocity was started in 2000 One of the first Jakarta projects ASF-licensed alternative to WebMacro Language syntax is similar and still very stable 100% Pure Java (runs on Java 1.3 or better) Velocity became an Apache TLP in 2006 Current release is 1.5 (as of March ’07)
Velocity Spotting Velocity is integrated with many other projects (Turbine, Struts 2, Maven…) and others  ( http:// wiki .apache.org/velocity/ PoweredByVelocity ) Support for IDEs and Editors available (e.g. Eclipse, IntelliJ IDEA, emacs…)  ( http:// wiki .apache.org/velocity/ VelocityEditors ) Response content in webapp frameworks (e.g. Struts, Turbine) Code generation (e.g. Torque, MyEclipse) Documentation (e.g. Maven, Anakia) Email (e.g. Spring)
Velocity vs JSP Easier to test No servlet container required Better separation of code and design No compilation into Java code Few, easy to learn language elements No embedded Java code! Easy on the eyes
Real Template Engines perl:  HTML-Template, Mason php:  Smarty, SmartTemplate,  TinyButStrong Ruby:  Galena, LiquidRuby Python:  QuickSilver, Cheetah,  TurboGears, Airspeed Java: WebMacro, FreeMarker,    Apache Velocity
Velocity Template Language Simple constructs # directive()  (line directives) #directive() … #end  (block directives) $ reference  or ${ reference } Embedded directly into template files (no open / close tags like JSP or PHP) References are “loosely typed” VTL can be learned in minutes
Assignments - #set() #set is used to create or update a reference #set( $foo = “text” )  String value #set( $foo = 100 ) Numeric value #set( $foo = [ 1, 2, 3 ] ) Array #set( $foo = { 1 : 2, 3 : 4 } ) Map #set( $foo = $bar ) Reference #set( $foo = $bar.foo )  Bean Property #set( $foo = $bar.doFoo() )  Method Result
Demo #1 - References #set( $message = ’Hello World’ ) This is a Velocity “$message” program. #set( $favorite = 137 ) My favorite number is not $favorite.
Display Control Elements Loop #foreach( $foo in $bars ) ... #end Conditional #if ( ) … #elseif ( ) … #else … #end Inclusion of external elements #include( ) Load external file #parse( ) Load and parse file
Demo #2 - Loops #set( $list =  [  ‘ a ’ ,  ‘ b ’ ,  ‘ c ’ ,  ‘ d ’  ]  ) #foreach(   $ alpha  in  $list  ) The current letter is $ alpha #end Let’s count  #foreach(   $i in [ 1..10 ]   )$i   #end
Demo #3 - Conditionals #if( $speaker eq ‘Henning’ )##Use german   Hallo Welt! #elseif( $hello ) $hello #else #*Use default greeting*#   Hi World! #end
Macros Builds a block directive on the fly Create:  #macro (name) … #end Use:  #name() … #end Velocity supports global and local scope Technically some sort of “method call”    (please don’t use it like this) For factoring out common template code/content
Macros Macros can take parameters Create:  #macro( name $arg $arg2 ) …$arg…$arg2…#end Use:  #name( $foo $bar ) … #end Arbitrary number of parameters possible Number of call parameters must match definition!
Demo #4 - Macros #macro( quote $value )"$value"#end We use a macro to quote #quote( 'this phrase' ).
Reference Syntax & Evaluation A  $ reference  represents a Java object Use a${ formalReference }to avoid parsing ambiguities $! ref or $!{ref}  means “be quiet when null”     (do not confuse with !$reference) Evaluation  always  invokes  toString() method
Velocity Miscellany A range operator exists #set ($foo = [ 1..100 ]) List of integers 1 to 100  Arithmetic (both integer  and floating point ) #set ($foo =  1.5  + 2 )  $foo is now 3.5 +, -, /, *, % Boolean operators for conditionals !, &&, ||, ==, <=, <, >, >= not, and, or, eq, ne, gt, ge, lt, le For == and !=, if the operands are not of the same class, their  toString()  values are compared String interpolation for #set(), macro args and method args #set( $foo = “foo was $foo” ) $foo is now “foo was 3.5”
Velocity Context The Context is the means of importing values into the template It is essentially a map of reference identifiers (i.e. the “foo” in ${foo}) to Java objects All access to data in the template comes this way There is no “natural” or “native” way to access or create Java objects
Demo – Using A Context public static void main(String [] args) throws Exception { VelocityEngine engine = new VelocityEngine(); VelocityContext context = new VelocityContext(); context.put(“speaker&quot;, “Nathan”); context.put(&quot;hello&quot;, &quot;Hello World!&quot;); Template template = engine.getTemplate(args[0]); StringWriter out = new StringWriter(); template.merge(context, out); System.out.println(out.toString()); }
Interacting With Context Objects The real power of Velocity All public methods in public classes are available All works via runtime reflection Shortcut notation for property access ($a.b vs $a.getB()) Type promotion as Java does Method parameters can not be omitted!   (this is not perl!)
VelocityTools A “tool” is just a context object that is “useful”  in a template Collection of useful Java classes. Comes in three flavors: GenericTools All-purpose tools VelocityView   Tools and more for webapps VelocityStruts Velocity as Struts View layer Other “tools” out there on the web
VelocityView VelocityViewServlet renders arbitrary Templates through web.xml mapping Configuration of tools with an XML based configuration file Different tool scopes/lifecycles possible ( application ,  session ,  request ) Request, Session, Response and ServletContext objects and their attributes are available automatically
Advanced Velocity Custom directives possible  (org.apache.velocity.runtime.directive.Directive) Multiple Resource loaders to load templates from different sources (files, classpath, jars, database, remote URLs) Event Handlers for Exception handling,  XML escaping , etc Custom Introspector for method and property access possible
Advanced Velocity Velocity Template Language (VTL) is defined in JavaCC grammar VTL itself can be changed or extended (needs recompilation of velocity.jar) More “Advanced Velocity“ at  http://wiki.apache.org/velocity/HackingVelocity   including the excellent ApacheCon 2004 session slides by Will Glass-Husain
Demo #5 - VelocityView Uses VelocityTools 2.0 (only alpha release available) VelocityViewServlet does the work Uses LinkTool, ParameterTool, EscapeTool  (aka $link, $params, and $esc) One custom tool: AddressBook is a ~30 line POJO One template: index.vm is just ~50 lines ~20 lines of config (including web.xml)
Velocity with Struts 1.x VelocityTools provides Struts tools for integration Seamless, not mutually exclusive with JSP (Image from http://velocity.apache.org/tools/devel/struts/!)
Velocity with Struts 1.x ActionMessagesTool - Action Messages ErrorsTool - Error Messages FormTool - Forms handling MessageTool - i18n Message Support StrutsLinkTool, SecureLinkTool - Links TilesTool - Struts-Tiles Framework ValidatorTool   - Validator Framework
Velocity with Turbine Preferred View Layer of Turbine No separate Servlet Turbine fully integrates Velocity Turbine provides infrastructure Tools Template Loaders Configuration and Logging
Velocity with… Velocity is supported as a first-class view layer in Struts 2.x (uses custom directives instead of tools) Spring MVC (also supports VelocityTools 1.x well) Click ( http://click.sourceforge.net/ ) Restlet ( http://www.restlet.org/ ) Mentawai (http://www.mentaframework.org/) And at least a dozen others… (http://wiki.apache.org/velocity/PoweredByVelocity)
Other Velocity Uses Texen  for generic text generation Anakia  for XML to documentation Torque – generate Java and SQL code VelocityViewTag – Easily embed Velocity in JSP  (Part of the upcoming VelocityTools 2.0) Velosurf – Tool for abstracting database interaction
Any questions?
Where to go from here? Velocity Homepage http://velocity.apache.org/ Velocity Mailing Lists http://velocity.apache.org/contact.html Velocity Wiki http://wiki.apache.org/velocity/ These Slides and Demo Code http://people.apache.org/~nbubna/oscon2007 Velocity 1.5 Release Notes http://wiki.apache.org/jakarta-velocity/Velocity15ReleaseNotes
Thanks for your attention!

More Related Content

PDF
Streams in Java 8
PDF
Productive Programming in Java 8 - with Lambdas and Streams
PPTX
Spl to the Rescue - Zendcon 09
PDF
Functional Thinking - Programming with Lambdas in Java 8
PDF
Functional Programming in Java 8 - Exploiting Lambdas
PDF
Codegeneration With Xtend
PDF
Recipes to build Code Generators for Non-Xtext Models with Xtend
PDF
Modern Programming in Java 8 - Lambdas, Streams and Date Time API
Streams in Java 8
Productive Programming in Java 8 - with Lambdas and Streams
Spl to the Rescue - Zendcon 09
Functional Thinking - Programming with Lambdas in Java 8
Functional Programming in Java 8 - Exploiting Lambdas
Codegeneration With Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
Modern Programming in Java 8 - Lambdas, Streams and Date Time API

What's hot (20)

PPT
55 New Features in Java 7
PPTX
New Features in JDK 8
PPT
Java Tut1
PPTX
Java Annotations and Pre-processing
PPTX
FFW Gabrovo PMG - PHP OOP Part 3
PDF
Java 8: the good parts!
PDF
Wien15 java8
PPTX
Java 8 Lambda and Streams
PDF
PHP 8: What's New and Changed
PPTX
Java 8 presentation
PDF
Java 8 Lambda Expressions & Streams
PPTX
10 Sets of Best Practices for Java 8
PDF
Java 8 ​and ​Best Practices
PPTX
Java 8 streams
PDF
Actor based approach in practice for Swift developers
PDF
Java 7 New Features
PPT
Helberg acl-final
PDF
Java SE 8 best practices
PDF
Java 5 and 6 New Features
PPTX
Lambda functions in java 8
55 New Features in Java 7
New Features in JDK 8
Java Tut1
Java Annotations and Pre-processing
FFW Gabrovo PMG - PHP OOP Part 3
Java 8: the good parts!
Wien15 java8
Java 8 Lambda and Streams
PHP 8: What's New and Changed
Java 8 presentation
Java 8 Lambda Expressions & Streams
10 Sets of Best Practices for Java 8
Java 8 ​and ​Best Practices
Java 8 streams
Actor based approach in practice for Swift developers
Java 7 New Features
Helberg acl-final
Java SE 8 best practices
Java 5 and 6 New Features
Lambda functions in java 8
Ad

Viewers also liked (6)

PPS
Struts Java I I Lecture 8
PDF
Build Java Web Application Using Apache Struts
PPT
Apachecon 2002 Struts
PDF
Study: The Future of VR, AR and Self-Driving Cars
PDF
Hype vs. Reality: The AI Explainer
Struts Java I I Lecture 8
Build Java Web Application Using Apache Struts
Apachecon 2002 Struts
Study: The Future of VR, AR and Self-Driving Cars
Hype vs. Reality: The AI Explainer
Ad

Similar to Apache Velocity (20)

PDF
Velocity 2pp
PPTX
Using velocity Templates(An overview)
PPTX
PPT
December 4 SDForum Java Sig Presentation
PDF
Dynamic and rich web application using the good ol\' JVM - Java One Brazil
PDF
Starting from scratch in 2017
KEY
Apache Velocity 1.6
PPTX
Be faster then rabbits
PDF
Web Application Frameworks - Lecture 05 - Web Information Systems (4011474FNR)
PDF
Java Edge.2009.Grails.Web.Dev.Made.Easy
PDF
Velocity tips and tricks
PDF
Linguistic Abstraction for the Web
PPTX
Java and the JVM
PPT
Developing Java Web Applications
PDF
Ola Bini Evolving The Java Platform
PDF
Lift talk
PDF
APIdays 2015 - The State of Web API Languages
PDF
APIdays 2015 - The State of Web API Languages
PDF
Moving to the Client - JavaFX and HTML5
PDF
New Features of Java7 SE
Velocity 2pp
Using velocity Templates(An overview)
December 4 SDForum Java Sig Presentation
Dynamic and rich web application using the good ol\' JVM - Java One Brazil
Starting from scratch in 2017
Apache Velocity 1.6
Be faster then rabbits
Web Application Frameworks - Lecture 05 - Web Information Systems (4011474FNR)
Java Edge.2009.Grails.Web.Dev.Made.Easy
Velocity tips and tricks
Linguistic Abstraction for the Web
Java and the JVM
Developing Java Web Applications
Ola Bini Evolving The Java Platform
Lift talk
APIdays 2015 - The State of Web API Languages
APIdays 2015 - The State of Web API Languages
Moving to the Client - JavaFX and HTML5
New Features of Java7 SE

Recently uploaded (20)

PDF
VCE English Exam - Section C Student Revision Booklet
PPTX
human mycosis Human fungal infections are called human mycosis..pptx
PDF
Classroom Observation Tools for Teachers
PDF
GENETICS IN BIOLOGY IN SECONDARY LEVEL FORM 3
PPTX
Pharma ospi slides which help in ospi learning
PPTX
GDM (1) (1).pptx small presentation for students
PPTX
1st Inaugural Professorial Lecture held on 19th February 2020 (Governance and...
PPTX
master seminar digital applications in india
PDF
STATICS OF THE RIGID BODIES Hibbelers.pdf
PDF
Complications of Minimal Access Surgery at WLH
PDF
Yogi Goddess Pres Conference Studio Updates
PDF
Weekly quiz Compilation Jan -July 25.pdf
PDF
Trump Administration's workforce development strategy
PDF
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
PPTX
Final Presentation General Medicine 03-08-2024.pptx
PPTX
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
PDF
OBE - B.A.(HON'S) IN INTERIOR ARCHITECTURE -Ar.MOHIUDDIN.pdf
PDF
Microbial disease of the cardiovascular and lymphatic systems
PDF
FourierSeries-QuestionsWithAnswers(Part-A).pdf
PPTX
Introduction-to-Literarature-and-Literary-Studies-week-Prelim-coverage.pptx
VCE English Exam - Section C Student Revision Booklet
human mycosis Human fungal infections are called human mycosis..pptx
Classroom Observation Tools for Teachers
GENETICS IN BIOLOGY IN SECONDARY LEVEL FORM 3
Pharma ospi slides which help in ospi learning
GDM (1) (1).pptx small presentation for students
1st Inaugural Professorial Lecture held on 19th February 2020 (Governance and...
master seminar digital applications in india
STATICS OF THE RIGID BODIES Hibbelers.pdf
Complications of Minimal Access Surgery at WLH
Yogi Goddess Pres Conference Studio Updates
Weekly quiz Compilation Jan -July 25.pdf
Trump Administration's workforce development strategy
A GUIDE TO GENETICS FOR UNDERGRADUATE MEDICAL STUDENTS
Final Presentation General Medicine 03-08-2024.pptx
school management -TNTEU- B.Ed., Semester II Unit 1.pptx
OBE - B.A.(HON'S) IN INTERIOR ARCHITECTURE -Ar.MOHIUDDIN.pdf
Microbial disease of the cardiovascular and lymphatic systems
FourierSeries-QuestionsWithAnswers(Part-A).pdf
Introduction-to-Literarature-and-Literary-Studies-week-Prelim-coverage.pptx

Apache Velocity

  • 1. Apache Velocity A Java Template Engine Nathan Bubna [email_address] , Henning P. Schmiedehausen [email_address] OSCON 2007, July 25th 2007 Portland, Oregon http://people.apache.org/~nbubna/oscon2007(.zip)
  • 2. Template Engine? Defines a simple language (VTL – Velocity Template Language) Templates are text containing active elements Active elements are replaced with values from the model No “industry standard” template language Templates are processed, not compiled
  • 3. Velocity Background Velocity was started in 2000 One of the first Jakarta projects ASF-licensed alternative to WebMacro Language syntax is similar and still very stable 100% Pure Java (runs on Java 1.3 or better) Velocity became an Apache TLP in 2006 Current release is 1.5 (as of March ’07)
  • 4. Velocity Spotting Velocity is integrated with many other projects (Turbine, Struts 2, Maven…) and others ( http:// wiki .apache.org/velocity/ PoweredByVelocity ) Support for IDEs and Editors available (e.g. Eclipse, IntelliJ IDEA, emacs…) ( http:// wiki .apache.org/velocity/ VelocityEditors ) Response content in webapp frameworks (e.g. Struts, Turbine) Code generation (e.g. Torque, MyEclipse) Documentation (e.g. Maven, Anakia) Email (e.g. Spring)
  • 5. Velocity vs JSP Easier to test No servlet container required Better separation of code and design No compilation into Java code Few, easy to learn language elements No embedded Java code! Easy on the eyes
  • 6. Real Template Engines perl: HTML-Template, Mason php: Smarty, SmartTemplate, TinyButStrong Ruby: Galena, LiquidRuby Python: QuickSilver, Cheetah, TurboGears, Airspeed Java: WebMacro, FreeMarker, Apache Velocity
  • 7. Velocity Template Language Simple constructs # directive() (line directives) #directive() … #end (block directives) $ reference or ${ reference } Embedded directly into template files (no open / close tags like JSP or PHP) References are “loosely typed” VTL can be learned in minutes
  • 8. Assignments - #set() #set is used to create or update a reference #set( $foo = “text” ) String value #set( $foo = 100 ) Numeric value #set( $foo = [ 1, 2, 3 ] ) Array #set( $foo = { 1 : 2, 3 : 4 } ) Map #set( $foo = $bar ) Reference #set( $foo = $bar.foo ) Bean Property #set( $foo = $bar.doFoo() ) Method Result
  • 9. Demo #1 - References #set( $message = ’Hello World’ ) This is a Velocity “$message” program. #set( $favorite = 137 ) My favorite number is not $favorite.
  • 10. Display Control Elements Loop #foreach( $foo in $bars ) ... #end Conditional #if ( ) … #elseif ( ) … #else … #end Inclusion of external elements #include( ) Load external file #parse( ) Load and parse file
  • 11. Demo #2 - Loops #set( $list = [ ‘ a ’ , ‘ b ’ , ‘ c ’ , ‘ d ’ ] ) #foreach( $ alpha in $list ) The current letter is $ alpha #end Let’s count #foreach( $i in [ 1..10 ] )$i #end
  • 12. Demo #3 - Conditionals #if( $speaker eq ‘Henning’ )##Use german Hallo Welt! #elseif( $hello ) $hello #else #*Use default greeting*# Hi World! #end
  • 13. Macros Builds a block directive on the fly Create: #macro (name) … #end Use: #name() … #end Velocity supports global and local scope Technically some sort of “method call” (please don’t use it like this) For factoring out common template code/content
  • 14. Macros Macros can take parameters Create: #macro( name $arg $arg2 ) …$arg…$arg2…#end Use: #name( $foo $bar ) … #end Arbitrary number of parameters possible Number of call parameters must match definition!
  • 15. Demo #4 - Macros #macro( quote $value )&quot;$value&quot;#end We use a macro to quote #quote( 'this phrase' ).
  • 16. Reference Syntax & Evaluation A $ reference represents a Java object Use a${ formalReference }to avoid parsing ambiguities $! ref or $!{ref} means “be quiet when null” (do not confuse with !$reference) Evaluation always invokes toString() method
  • 17. Velocity Miscellany A range operator exists #set ($foo = [ 1..100 ]) List of integers 1 to 100 Arithmetic (both integer and floating point ) #set ($foo = 1.5 + 2 ) $foo is now 3.5 +, -, /, *, % Boolean operators for conditionals !, &&, ||, ==, <=, <, >, >= not, and, or, eq, ne, gt, ge, lt, le For == and !=, if the operands are not of the same class, their toString() values are compared String interpolation for #set(), macro args and method args #set( $foo = “foo was $foo” ) $foo is now “foo was 3.5”
  • 18. Velocity Context The Context is the means of importing values into the template It is essentially a map of reference identifiers (i.e. the “foo” in ${foo}) to Java objects All access to data in the template comes this way There is no “natural” or “native” way to access or create Java objects
  • 19. Demo – Using A Context public static void main(String [] args) throws Exception { VelocityEngine engine = new VelocityEngine(); VelocityContext context = new VelocityContext(); context.put(“speaker&quot;, “Nathan”); context.put(&quot;hello&quot;, &quot;Hello World!&quot;); Template template = engine.getTemplate(args[0]); StringWriter out = new StringWriter(); template.merge(context, out); System.out.println(out.toString()); }
  • 20. Interacting With Context Objects The real power of Velocity All public methods in public classes are available All works via runtime reflection Shortcut notation for property access ($a.b vs $a.getB()) Type promotion as Java does Method parameters can not be omitted! (this is not perl!)
  • 21. VelocityTools A “tool” is just a context object that is “useful” in a template Collection of useful Java classes. Comes in three flavors: GenericTools All-purpose tools VelocityView Tools and more for webapps VelocityStruts Velocity as Struts View layer Other “tools” out there on the web
  • 22. VelocityView VelocityViewServlet renders arbitrary Templates through web.xml mapping Configuration of tools with an XML based configuration file Different tool scopes/lifecycles possible ( application , session , request ) Request, Session, Response and ServletContext objects and their attributes are available automatically
  • 23. Advanced Velocity Custom directives possible (org.apache.velocity.runtime.directive.Directive) Multiple Resource loaders to load templates from different sources (files, classpath, jars, database, remote URLs) Event Handlers for Exception handling, XML escaping , etc Custom Introspector for method and property access possible
  • 24. Advanced Velocity Velocity Template Language (VTL) is defined in JavaCC grammar VTL itself can be changed or extended (needs recompilation of velocity.jar) More “Advanced Velocity“ at http://wiki.apache.org/velocity/HackingVelocity including the excellent ApacheCon 2004 session slides by Will Glass-Husain
  • 25. Demo #5 - VelocityView Uses VelocityTools 2.0 (only alpha release available) VelocityViewServlet does the work Uses LinkTool, ParameterTool, EscapeTool (aka $link, $params, and $esc) One custom tool: AddressBook is a ~30 line POJO One template: index.vm is just ~50 lines ~20 lines of config (including web.xml)
  • 26. Velocity with Struts 1.x VelocityTools provides Struts tools for integration Seamless, not mutually exclusive with JSP (Image from http://velocity.apache.org/tools/devel/struts/!)
  • 27. Velocity with Struts 1.x ActionMessagesTool - Action Messages ErrorsTool - Error Messages FormTool - Forms handling MessageTool - i18n Message Support StrutsLinkTool, SecureLinkTool - Links TilesTool - Struts-Tiles Framework ValidatorTool - Validator Framework
  • 28. Velocity with Turbine Preferred View Layer of Turbine No separate Servlet Turbine fully integrates Velocity Turbine provides infrastructure Tools Template Loaders Configuration and Logging
  • 29. Velocity with… Velocity is supported as a first-class view layer in Struts 2.x (uses custom directives instead of tools) Spring MVC (also supports VelocityTools 1.x well) Click ( http://click.sourceforge.net/ ) Restlet ( http://www.restlet.org/ ) Mentawai (http://www.mentaframework.org/) And at least a dozen others… (http://wiki.apache.org/velocity/PoweredByVelocity)
  • 30. Other Velocity Uses Texen for generic text generation Anakia for XML to documentation Torque – generate Java and SQL code VelocityViewTag – Easily embed Velocity in JSP (Part of the upcoming VelocityTools 2.0) Velosurf – Tool for abstracting database interaction
  • 32. Where to go from here? Velocity Homepage http://velocity.apache.org/ Velocity Mailing Lists http://velocity.apache.org/contact.html Velocity Wiki http://wiki.apache.org/velocity/ These Slides and Demo Code http://people.apache.org/~nbubna/oscon2007 Velocity 1.5 Release Notes http://wiki.apache.org/jakarta-velocity/Velocity15ReleaseNotes
  • 33. Thanks for your attention!