A Rapid Prototyping MVC Framework       based on Groovy / Java       by Jeroen Wesbeek <work@osx.eu>
What is Grails?A Groovy / Java Web Framework that is
What is Grails?A Groovy / Java Web Framework that is• Rapid
What is Grails?A Groovy / Java Web Framework that is• Rapid• Dynamic
What is Grails?A Groovy / Java Web Framework that is• Rapid• Dynamic• Robust
Grails is Rapid?Yes! You will have a functional application in about eight                        seconds!
That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by:
That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by: • eliminating XML configura...
That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by: • eliminating XML configura...
That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by: • eliminating XML configura...
Rapid Development As Grails is inspired by the RAILS principle, itprovides 52 commands to make your life easier:•   grails...
“If we had built our prototype inJava, we would have only beenable to deliver a quarter to athird of the functionality wep...
“Now using Groovy and Grails,   we release every week to  production, compared with every six weeks previously”           ...
“I cannot count how many   times we have exclaimed“WOW!” realizing how Grailsmakes things easy. Grails turned out to be de...
Why is it dynamic?• Changes made in Controllers and Views are  instantly visible - Domain Classes, Bootstrap and Configurat...
Grails is RobustGrails builds upon proven technology:
Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine...
Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine...
Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine...
Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine...
Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:
Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:...
Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:...
Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:...
How is a grailsapplication built-up?
How is a grails          application built-up?Application Code
How is a grails       application built-up?Libraries
How is a grails        application built-up?Tests
How is a grails           application built-up?JS / CSS / Images
How is a grails         application built-up?Controllers
How is a grails         application built-up?Domain Classes
How is a grails    application built-up?Views
How is a grails        application built-up?Configuration
How is a grails            application built-up?Internationalization
How is a grails      application built-up?Services
How is a grails         application built-up?Tag Libraries
The Library AplicationWe will set up a simple library application which        will contain Authors and Books
The Library AplicationWe will set up a simple library application which        will contain Authors and Books • create dom...
The Library AplicationWe will set up a simple library application which        will contain Authors and Books • create dom...
Domain Classes
Domain Classes
Domain Classes
Domain Classes  This will generate Domain Classes             and Unit Tests
Author Domain Class
Author Domain ClassAuthor name
Author Domain ClassBook Relationship
Book Domain Class
Book Domain ClassBook Title
Book Domain ClassRelationship
Book Domain ClassRelationship                    “Book” belongs to “Author”  Updates made to Author will be cascaded down ...
Book Domain Class                                                        Grails                                           ...
MVC: The ModelTo Summarize, we created:
MVC: The ModelTo Summarize, we created:• an Author Domain Class which has many  Books
MVC: The ModelTo Summarize, we created:• an Author Domain Class which has many  Books• a Book Domain Class which belongs t...
MVC: The ModelTo Summarize, we created:• an Author Domain Class which has many  Books• a Book Domain Class which belongs t...
The Controllers
The Controllers
The Controllers
The ControllersEnable ScaffoldingEnable Scaffolding
The ControllersDisable default indexDisable default index
The Controllers                              Note this is                             a closure, not                      ...
The Controllers                                  Note this is                                 a closure, not              ...
The Controllers                                  Note this is                                 a closure, not              ...
The ControllersScaffolding dynamically creates a CRUD  user interface for your controllers
Running The Application
Running The Application
We would like to show Dan Brown instead
Author Domain Class
Author Domain ClassOverload toString
Author Domain ClassOverload toString                    ‘return’ is not                       required
Author name is now shown       as expected
To summarize
To summarize• in a short period of time you can have a  basic functional application with a CRUD  interface to your Domain...
To summarize• in a short period of time you can have a  basic functional application with a CRUD  interface to your Domain...
To summarize• in a short period of time you can have a  basic functional application with a CRUD  interface to your Domain...
Cascading
CascadingRelationship
CascadingRelationship               If an author is deleted, his books                 are cascadingly deleted as well
Why is it dynamic?• Changes made in Controllers and Views are  instantly visible - Domain Classes, Bootstrap and Configurat...
How to continue?
How to continue?Replace the default CRUD interface     with your own interface
How to continue?Replace the default CRUD interface     with your own interface
How to continue?                Replace the default CRUD interface                     with your own interfacedisable scaf...
How to continue?                Replace the default CRUD interface                     with your own interfacedisable scaf...
How to continue?                Replace the default CRUD interface                     with your own interfacedisable scaf...
Author index view
Author index view
Author index view
Author index view
Author index viewGrails leverages Sitemesh, a decorator  engine, to support view layouts.
Author index viewGrails leverages Sitemesh, a decorator  engine, to support view layouts.
Author index viewGrails leverages Sitemesh, a decorator  engine, to support view layouts.                                 ...
Author index viewGrails leverages Sitemesh, a decorator  engine, to support view layouts.                                 ...
Author index view
Author Index View
Author Index View ‘form’ tag
Author Index View ‘form’ tag              ‘select’ tag
Author Index View ‘form’ tag                           ‘select’ tag              ‘each’ tag
Author Index View      ‘form’ tag                                   ‘select’ tag                      ‘each’ tagYou can cr...
Author Index View             the form will submit to the         ‘author’ controller’s ‘index’ action
Author Controller
Author Controller       if we get an author’s name from the      view, fetch an instance of that Author
Author Controller    Return a       if we get an author’s name from theLinkedHashMap     view, fetch an instance of that A...
Author Controller    Return a       if we get an author’s name from theLinkedHashMap     view, fetch an instance of that A...
Author Controller    Return a       if we get an author’s name from theLinkedHashMap     view, fetch an instance of that A...
Author Controller    Return a       if we get an author’s name from theLinkedHashMap     view, fetch an instance of that A...
Author View
Plugins
Plugins                  GWT          GORM Support for Hadoop HBase Grails Webflows                                       G...
Plugins We Developed
Plugins We Developed                                 AjaxFlowGDT (Grails Domain Temlates)                  Grom           ...
Plugins We Developed                                               In Grails Central                                 AjaxF...
Plugins We Developed                                                In Grails Central                                  Aja...
Plugins We Developed                                                               In Grails Central                      ...
Release Management
Release Management• With a single command you can build a test  or production package (e.g. grails prod war)
Release Management• With a single command you can build a test  or production package (e.g. grails prod war)• Configuring P...
Release Management• With a single command you can build a test  or production package (e.g. grails prod war)• Configuring P...
To SummariseGrails is
To SummariseGrails is• Rapid
To SummariseGrails is• Rapid     you can focus on what matters!
To SummariseGrails is• Rapid     you can focus on what matters!• Dynamic
To SummariseGrails is• Rapid        you can focus on what matters!• Dynamic   no boilerplate code & free functionality
To SummariseGrails is• Rapid        you can focus on what matters!• Dynamic   no boilerplate code & free functionality• Ro...
To SummariseGrails is• Rapid        you can focus on what matters!• Dynamic   no boilerplate code & free functionality• Ro...
Any Questions? :)                by Jeroen Wesbeek <work@osx.eu>Presentation also available on http://grails.nmcdsp.org/
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Groovy & Grails Introductory Presentation
Upcoming SlideShare
Loading in...5
×

Groovy & Grails Introductory Presentation

1,484

Published on

This is a presentation I gave at the Netherlands Bio Informatics Consortium's BioAssist meetings about the Grails MVC Web Framework. It's a Rapid Prototyping MVC Framework based on Groovy / Java, based on to the RAILS paradigm. As it is built upon proven technology (Spring, Hibernate, etcetera) and can mix Groovy with Java code, the projects developed by the Java world are all usable in the Grails framework which makes it very powerful and easy to extend.

0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total Views
1,484
On Slideshare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
136
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • \n
  • Groovy & Grails Introductory Presentation

    1. 1. A Rapid Prototyping MVC Framework based on Groovy / Java by Jeroen Wesbeek <work@osx.eu>
    2. 2. What is Grails?A Groovy / Java Web Framework that is
    3. 3. What is Grails?A Groovy / Java Web Framework that is• Rapid
    4. 4. What is Grails?A Groovy / Java Web Framework that is• Rapid• Dynamic
    5. 5. What is Grails?A Groovy / Java Web Framework that is• Rapid• Dynamic• Robust
    6. 6. Grails is Rapid?Yes! You will have a functional application in about eight seconds!
    7. 7. That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by:
    8. 8. That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by: • eliminating XML configuration - Convention over Configuration. For example, a class name which ends with Controller (e.g. BookController) is considered a web controller
    9. 9. That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by: • eliminating XML configuration - Convention over Configuration. For example, a class name which ends with Controller (e.g. BookController) is considered a web controller • ready to use development environment - Grails comes with a complete development environment which includes a webserver and a database
    10. 10. That’s nice, what else?Grails aims to improve productivity overconventional Java Frameworks by: • eliminating XML configuration - Convention over Configuration. For example, a class name which ends with Controller (e.g. BookController) is considered a web controller • ready to use development environment - Grails comes with a complete development environment which includes a webserver and a database • default functionality through mixins - methods which are added to a class dynamically as if the functionality was compiled in the program, like getters and setters and dynamic finders
    11. 11. Rapid Development As Grails is inspired by the RAILS principle, itprovides 52 commands to make your life easier:• grails create-app• grails create-domain-class• grails create-controller• grails install-plugin• grails war
    12. 12. “If we had built our prototype inJava, we would have only beenable to deliver a quarter to athird of the functionality weproduced in Groovy and Grails” Paul Fisher, Tech Mgr Wired.com
    13. 13. “Now using Groovy and Grails, we release every week to production, compared with every six weeks previously” Jon Mullen, ScrumMaster Sky.com
    14. 14. “I cannot count how many times we have exclaimed“WOW!” realizing how Grailsmakes things easy. Grails turned out to be definitely the right choice.” Vincenzo Foderà Vodafone Music Store
    15. 15. Why is it dynamic?• Changes made in Controllers and Views are instantly visible - Domain Classes, Bootstrap and Configuration require a recompile• Default functionality through mixins
    16. 16. Grails is RobustGrails builds upon proven technology:
    17. 17. Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine that offers a flexible Java-like syntax that most Java developers can learn in matter of hours and compiles to bytecode
    18. 18. Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine that offers a flexible Java-like syntax that most Java developers can learn in matter of hours and compiles to bytecode • Spring - an open source Java Application Framework
    19. 19. Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine that offers a flexible Java-like syntax that most Java developers can learn in matter of hours and compiles to bytecode • Spring - an open source Java Application Framework • Hibernate - an Object Relational Mapping (ORM) Framework
    20. 20. Grails is RobustGrails builds upon proven technology: • Groovy - open source dynamic language for the Java Virtual Machine that offers a flexible Java-like syntax that most Java developers can learn in matter of hours and compiles to bytecode • Spring - an open source Java Application Framework • Hibernate - an Object Relational Mapping (ORM) FrameworkGrails is backed by SpringSource / VMwareContinued development and support guaranteed
    21. 21. Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:
    22. 22. Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:• Data - The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).
    23. 23. Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:• Data - The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).• User Interface - The view renders the model into a form suitable for interaction, typically a user interface element.
    24. 24. Model View Controller?MVC is a software architectural pattern which dates back to1979 and is widely adopted. It separates:• Data - The model manages the behavior and data of the application domain, responds to requests for information about its state (usually from the view), and responds to instructions to change state (usually from the controller).• User Interface - The view renders the model into a form suitable for interaction, typically a user interface element.• Application Logic - The controller receives user input and initiates a response by making calls on model objects.
    25. 25. How is a grailsapplication built-up?
    26. 26. How is a grails application built-up?Application Code
    27. 27. How is a grails application built-up?Libraries
    28. 28. How is a grails application built-up?Tests
    29. 29. How is a grails application built-up?JS / CSS / Images
    30. 30. How is a grails application built-up?Controllers
    31. 31. How is a grails application built-up?Domain Classes
    32. 32. How is a grails application built-up?Views
    33. 33. How is a grails application built-up?Configuration
    34. 34. How is a grails application built-up?Internationalization
    35. 35. How is a grails application built-up?Services
    36. 36. How is a grails application built-up?Tag Libraries
    37. 37. The Library AplicationWe will set up a simple library application which will contain Authors and Books
    38. 38. The Library AplicationWe will set up a simple library application which will contain Authors and Books • create domain classes
    39. 39. The Library AplicationWe will set up a simple library application which will contain Authors and Books • create domain classes • let Grails generate a CRUD (CReate Update Delete) interface
    40. 40. Domain Classes
    41. 41. Domain Classes
    42. 42. Domain Classes
    43. 43. Domain Classes This will generate Domain Classes and Unit Tests
    44. 44. Author Domain Class
    45. 45. Author Domain ClassAuthor name
    46. 46. Author Domain ClassBook Relationship
    47. 47. Book Domain Class
    48. 48. Book Domain ClassBook Title
    49. 49. Book Domain ClassRelationship
    50. 50. Book Domain ClassRelationship “Book” belongs to “Author” Updates made to Author will be cascaded down to Book by GORM!
    51. 51. Book Domain Class Grails ObjectRelationship Relational Mapping “Book” belongs to “Author” Updates made to Author will be cascaded down to Book by GORM!
    52. 52. MVC: The ModelTo Summarize, we created:
    53. 53. MVC: The ModelTo Summarize, we created:• an Author Domain Class which has many Books
    54. 54. MVC: The ModelTo Summarize, we created:• an Author Domain Class which has many Books• a Book Domain Class which belongs to Author and is cascadedly updated or deleted
    55. 55. MVC: The ModelTo Summarize, we created:• an Author Domain Class which has many Books• a Book Domain Class which belongs to Author and is cascadedly updated or deleted Author 1:n Book
    56. 56. The Controllers
    57. 57. The Controllers
    58. 58. The Controllers
    59. 59. The ControllersEnable ScaffoldingEnable Scaffolding
    60. 60. The ControllersDisable default indexDisable default index
    61. 61. The Controllers Note this is a closure, not a method!Disable default indexDisable default index
    62. 62. The Controllers Note this is a closure, not a method!Disable default index def myMethod() { ... }Disable default index
    63. 63. The Controllers Note this is a closure, not a method!Disable default index def myMethod() { ... } def myClosure { ... }Disable default index
    64. 64. The ControllersScaffolding dynamically creates a CRUD user interface for your controllers
    65. 65. Running The Application
    66. 66. Running The Application
    67. 67. We would like to show Dan Brown instead
    68. 68. Author Domain Class
    69. 69. Author Domain ClassOverload toString
    70. 70. Author Domain ClassOverload toString ‘return’ is not required
    71. 71. Author name is now shown as expected
    72. 72. To summarize
    73. 73. To summarize• in a short period of time you can have a basic functional application with a CRUD interface to your Domain model
    74. 74. To summarize• in a short period of time you can have a basic functional application with a CRUD interface to your Domain model• you don’t need to set up a relational database yourself as you define your datamodel in code and GORM / Hibernate takes care of the rest
    75. 75. To summarize• in a short period of time you can have a basic functional application with a CRUD interface to your Domain model• you don’t need to set up a relational database yourself as you define your datamodel in code and GORM / Hibernate takes care of the rest• no XML configuration has to be done
    76. 76. Cascading
    77. 77. CascadingRelationship
    78. 78. CascadingRelationship If an author is deleted, his books are cascadingly deleted as well
    79. 79. Why is it dynamic?• Changes made in Controllers and Views are instantly visible - Domain Classes, Bootstrap and Configuration require a recompile• Default functionality through mixins
    80. 80. How to continue?
    81. 81. How to continue?Replace the default CRUD interface with your own interface
    82. 82. How to continue?Replace the default CRUD interface with your own interface
    83. 83. How to continue? Replace the default CRUD interface with your own interfacedisable scaffolding
    84. 84. How to continue? Replace the default CRUD interface with your own interfacedisable scaffolding ...and re-enable the index closure
    85. 85. How to continue? Replace the default CRUD interface with your own interfacedisable scaffolding ...and re-enable the index closure Grails will now use the view: grails-app/views/author/index.gsp
    86. 86. Author index view
    87. 87. Author index view
    88. 88. Author index view
    89. 89. Author index view
    90. 90. Author index viewGrails leverages Sitemesh, a decorator engine, to support view layouts.
    91. 91. Author index viewGrails leverages Sitemesh, a decorator engine, to support view layouts.
    92. 92. Author index viewGrails leverages Sitemesh, a decorator engine, to support view layouts. we tell Sitemesh to use the main layout for decorating the index page
    93. 93. Author index viewGrails leverages Sitemesh, a decorator engine, to support view layouts. we tell Sitemesh to use the main layout for decorating the index page layouts are stored in the views/layouts folder
    94. 94. Author index view
    95. 95. Author Index View
    96. 96. Author Index View ‘form’ tag
    97. 97. Author Index View ‘form’ tag ‘select’ tag
    98. 98. Author Index View ‘form’ tag ‘select’ tag ‘each’ tag
    99. 99. Author Index View ‘form’ tag ‘select’ tag ‘each’ tagYou can create your own tags by creating new tag libaries
    100. 100. Author Index View the form will submit to the ‘author’ controller’s ‘index’ action
    101. 101. Author Controller
    102. 102. Author Controller if we get an author’s name from the view, fetch an instance of that Author
    103. 103. Author Controller Return a if we get an author’s name from theLinkedHashMap view, fetch an instance of that Author to the view
    104. 104. Author Controller Return a if we get an author’s name from theLinkedHashMap view, fetch an instance of that Author to the view containing the Author instance
    105. 105. Author Controller Return a if we get an author’s name from theLinkedHashMap view, fetch an instance of that Author to the view containing the Author instance an ArrayList of Authors
    106. 106. Author Controller Return a if we get an author’s name from theLinkedHashMap view, fetch an instance of that Author to the view containing the Author instance an ArrayList of Authors an ArrayList of all books for a given Author
    107. 107. Author View
    108. 108. Plugins
    109. 109. Plugins GWT GORM Support for Hadoop HBase Grails Webflows Google Visualisation jQuery Vaadin Spring Security 579 OAuth ShoppingCartCloudFoundry OpenID Spring WS MongoDB Google AppEngine Quartz
    110. 110. Plugins We Developed
    111. 111. Plugins We Developed AjaxFlowGDT (Grails Domain Temlates) Grom Uploadr GDT Importer
    112. 112. Plugins We Developed In Grails Central AjaxFlow Plugin RepositoryGDT (Grails Domain Temlates) Grom Uploadr GDT Importer
    113. 113. Plugins We Developed In Grails Central AjaxFlow Plugin Repository GDT (Grails Domain Temlates) Grom Uploadrin Maven repository GDT Importer
    114. 114. Plugins We Developed In Grails Central AjaxFlow Plugin Repository GDT (Grails Domain Temlates) Grom Uploadrin Maven repository GDT Importerhttp://nexus.nmcdsp.org Source on GitHubhttps://github.com/PhenotypeFoundation https://github.com/4np/grails-ajaxflowhttps://github.com/NetherlandsMetabolomicsCentre https://github.com/4np/grails-grom https://github.com/4np/grails-uploadr
    115. 115. Release Management
    116. 116. Release Management• With a single command you can build a test or production package (e.g. grails prod war)
    117. 117. Release Management• With a single command you can build a test or production package (e.g. grails prod war)• Configuring PostgreSQL / MySQL / MongoDB etc for different environments is a blast
    118. 118. Release Management• With a single command you can build a test or production package (e.g. grails prod war)• Configuring PostgreSQL / MySQL / MongoDB etc for different environments is a blast• Testing / Continuous integration is easy due to Hudson’s Grails Support (plugin)
    119. 119. To SummariseGrails is
    120. 120. To SummariseGrails is• Rapid
    121. 121. To SummariseGrails is• Rapid you can focus on what matters!
    122. 122. To SummariseGrails is• Rapid you can focus on what matters!• Dynamic
    123. 123. To SummariseGrails is• Rapid you can focus on what matters!• Dynamic no boilerplate code & free functionality
    124. 124. To SummariseGrails is• Rapid you can focus on what matters!• Dynamic no boilerplate code & free functionality• Robust
    125. 125. To SummariseGrails is• Rapid you can focus on what matters!• Dynamic no boilerplate code & free functionality• Robust backed by a large community
    126. 126. Any Questions? :) by Jeroen Wesbeek <work@osx.eu>Presentation also available on http://grails.nmcdsp.org/
    1. A particular slide catching your eye?

      Clipping is a handy way to collect important slides you want to go back to later.

    ×