Unlock Enterprise Databases to Create New Online Services with Magnolia and Grails
-
Upload
boris-kraft -
Category
Technology
-
view
262 -
download
1
description
Transcript of Unlock Enterprise Databases to Create New Online Services with Magnolia and Grails
WebCastPeter Wayner
1
Magnolia + Grails = Maglev
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
WebCastPeter Wayner
2
MaglevTable-driven data with GrailsTemplate-driven pages with Magnolia
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
3
Is it possible to mix the ease of Grails with the
Magnolia?
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
4
Yes! With Maglev, a plugin
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
5
Grails is a Java-based Web App FrameworkGrails is open sourceGrails is template-driven (GSP and JSP)Grails is extendable with plugins.
Why?
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
6
Magnolia is a Java-based Content Management SystemMagnolia is open sourceMagnolia is template-driven (Freemarker and JSP)Magnolia is extendable with plugins.
Magnolia is Similar
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
7
Developed by Kimmo Björnsson and Åke Argéus, Lead Developers, Bonheur ABThey saw that the two tools that complemented each other well.They turned Magnolia into a plugin that lives in Grails.
Invention
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
8
Maglev bundles together all of Magnolia into a Grails plugin.It’s plugged into Grails, but Magnolia ends up driving the front.Grails handles the table-driven objects.Magnolia handles the templates
Let’s mix them together
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
9
Rapid prototyping. Grails builds databases quickly.Data/Content integration. Magnolia knits together content well.Separation of code from presentation. (Grails handles backend, Magnolia the front.)
Benefits
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
10
Affiliate marketing for a web site needs a table of URLs. If someone clicks on the URL, the web site gets some revenue.Lets store them in a table.Display them in a Magnolia template.
Example
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
11
class AffiliateItem {
String name // The item being advertised.
Date dateCreated // When started.
String url // Where the item can be purchased.
String shortDescription // A short description.
String longDescription // A long description.
Date startDate // When available.
Date stopDate // The last day it is available.
}
Grails just needs an object definition
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
12
class AffiliateItem {
static constraints = {
name blank:false, unique:true
url url:true,blank:false, unique:true
shortDescription maxSize:26
longDescription widget:textarea
}
/// ….
Grails lets you add constraints
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
13
class AffiliateItemController{
static scaffold = true
}
Just add a controller
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
14
Grails builds CRUD (create, update, delete) routines for object tables. You start up Grails and it analyzes your object definition.Then it creates all of the code necessary to let you build up tables filled with the objects.
One button and Grails Finishes
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
15
package testgrails1
import org.springframework.dao.DataIntegrityViolationException
class AffiliateItemController {
static allowedMethods = [save: "POST", update: "POST", delete: "POST"]
def index() {
redirect(action: "list", params: params)
}
def list() {
params.max = Math.min(params.max ? params.int('max') : 10, 100)
[affiliateItemInstanceList: AffiliateItem.list(params), affiliateItemInstanceTotal: AffiliateItem.count()]
}
def create() {
[affiliateItemInstance: new AffiliateItem(params)]
}
def save() {
def affiliateItemInstance = new AffiliateItem(params)
if (!affiliateItemInstance.save(flush: true)) {
render(view: "create", model: [affiliateItemInstance: affiliateItemInstance])
return
}
flash.message = message(code: 'default.created.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), affiliateItemInstance.id])
redirect(action: "show", id: affiliateItemInstance.id)
}
def show() {
def affiliateItemInstance = AffiliateItem.get(params.id)
if (!affiliateItemInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), params.id])
redirect(action: "list")
return
}
[affiliateItemInstance: affiliateItemInstance]
}
def edit() {
def affiliateItemInstance = AffiliateItem.get(params.id)
if (!affiliateItemInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), params.id])
redirect(action: "list")
return
}
[affiliateItemInstance: affiliateItemInstance]
}
def update() {
def affiliateItemInstance = AffiliateItem.get(params.id)
if (!affiliateItemInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), params.id])
redirect(action: "list")
return
}
if (params.version) {
def version = params.version.toLong()
if (affiliateItemInstance.version > version) {
affiliateItemInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
[message(code: 'affiliateItem.label', default: 'AffiliateItem')] as Object[],
"Another user has updated this AffiliateItem while you were editing")
render(view: "edit", model: [affiliateItemInstance: affiliateItemInstance])
return
}
}
affiliateItemInstance.properties = params
if (!affiliateItemInstance.save(flush: true)) {
render(view: "edit", model: [affiliateItemInstance: affiliateItemInstance])
return
}
flash.message = message(code: 'default.updated.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), affiliateItemInstance.id])
redirect(action: "show", id: affiliateItemInstance.id)
}
def delete() {
def affiliateItemInstance = AffiliateItem.get(params.id)
if (!affiliateItemInstance) {
flash.message = message(code: 'default.not.found.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), params.id])
redirect(action: "list")
return
}
try {
affiliateItemInstance.delete(flush: true)
flash.message = message(code: 'default.deleted.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), params.id])
redirect(action: "list")
}
catch (DataIntegrityViolationException e) {
flash.message = message(code: 'default.not.deleted.message', args: [message(code: 'affiliateItem.label', default: 'AffiliateItem'), params.id])
redirect(action: "show", id: params.id)
}
}
}
Just some of the code built by Grails for free
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
16
What the user sees
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
17
Magnolia just needs a controller that can search the tables for what it wants.A template can format what is found.
What Magnolia Does
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
18
import info.magnolia.module.blossom.annotation.Template
@Template(id = "grailsModule:pages/demoTemplate", title = "Demo
template")
class MainTemplateController {
def index() {
[count:AffiliateItem.count(), items:AffiliateItem.list()]
}
}
MainTemplateController
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
19
There are some static methods for looking through the tables of AffiliateItems.
import info.magnolia.module.blossom.annotation.Template
@Template(id = "grailsModule:pages/demoTemplate", title = "Demo
template")
class MainTemplateController {
def index() {
[count:AffiliateItem.count(), items:AffiliateItem.list()]
}
}
MainTemplateController
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
20
The index method calls the static search methods and bundles the results into a data structure for the template. You can add extra search logic and filtering here.
import info.magnolia.module.blossom.annotation.Template
@Template(id = "grailsModule:pages/demoTemplate", title = "Demo
template")
class MainTemplateController {
def index() {
[count:AffiliateItem.count(), items:AffiliateItem.list()]
}
}
MainTemplateController
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
21
The Template annotation connects the controller with the templates.
import info.magnolia.module.blossom.annotation.Template
@Template(id = "grailsModule:pages/demoTemplate", title = "Demo
template")
class MainTemplateController {
def index() {
[count:AffiliateItem.count(), items:AffiliateItem.list()]
}
}
MainTemplateController
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
22
<div class="body">
There are <i> <%= count %></i> AffiliateItems
<ul>
<g:each in="${items}" var="x">
<li><a href=”${x.url}”>${x.name}</a> --
<i>${x.longDescription}</i></li> </g:each>
</ul>
</div>
Index.gsp
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
23
The count is just a number collected from the AffiliateItem.count() static routine in the Controller.
<div class="body">
There are <i> <%= count %></i> AffiliateItems
<ul>
<g:each in="${items}" var="x">
<li><a href=”${x.url}”>${x.name}</a> --
<i>${x.longDescription}</i></li> </g:each>
</ul>
</div>
Index.gsp
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
24
Grails loops through the list of objects created by the AffiliateItem.list() method in the Controller.
<div class="body">
There are <i> <%= count %></i> AffiliateItems
<ul>
<g:each in="${items}" var="x">
<li><a href=”${x.url}”>${x.name}</a> --
<i>${x.longDescription}</i></li> </g:each>
</ul>
</div>
Index.gsp
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
25
Index.gsp becomes a template for MagnoliaMagnolia glues it together into the web site like all of the other templates and blocksThe Grails blocks sit next to the others.
Magnolia Takes Over
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
26
More complicated templates.More logic in the Controllers.Magnolia glues them all together in a nice layout.
What Next?
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
27
Introduction http://wiki.magnolia-cms.com/display/TALKOOT/Creating+Database-driven+Web+Applications+with+Magnolia+CMS,+Groovy+and+Maglev
Maglev quickstart
https://github.com/Bonheur/maglev/wiki/Quick-
Start
Maglev downloads
https://github.com/Bonheur/maglev/downloads
Maglev JIRA site. http://
jira.magnolia-cms.com/browse/MAGLEV
http://www.magnolia-cms.com/community/magnolia-
conference/program/presentation-day/
presentations/bonheur-ab.html
Resources
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
28 Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
29 Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
Section title with abstract
30 Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
Section titlewith image
31
Lay the foundation for future successImprove usabilitySimplify customizationLower the entry barrierDon’t change what worksProvide a migration path
List of points without subtopics
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
32
Editor
• Exposed by View (HasEditors)
• Populate View with data
• Retrieve values entered by user
Driver
• Injects values into editors
• Updates underlying model (node, bean)
• Validates data
Used in various editable views
• DialogView, TreeView, ParagraphEditView…
Title and bullets
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
33
Enterprise Edition
• Best choice for mission critical websites
• Supported by the vendor
• Advanced enterprise features
• Visible source via Magnolia Network Agreement
• Cost effective
• Double the Speed
Community Edition
• Basic content management functionality
• Supported by the community
• Free for unlimited use
• Open source
• Cost effective
• Double the Speed
Title and bullets – 2 columns
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
34
POJOs (Definitions)
• Dialogs, trees, actions
• Vaadin independentContributed in various ways
• Configuration
• Annotations
• ProgrammaticallyUI Builder builds the Vaadin components
Title, bullets & picture
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
35
Title and picture horizontal
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
36 Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
Series 1, 2, 3, 4Each step one slide
1 2 3 4
37
Where does great content come from?
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
38
It takes about ten seconds to explain how to create
content!
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
39
Clouds
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.
DevelopmentAuthoring
Accessibility
Configuration UIWizards
Developer mode
AdminCentralPage editing
ClipboardSaved lists
Search
KeyboardLTR/RTL
MobileTouch
DD.MM.YYYY at Venue/[email protected]
First Last, RoleMagnolia International Ltd.
40
www.magnolia-cms.com
Final slide
Version 1.1 Magnolia is a registered trademark owned by Magnolia International Ltd.