Webinar with Tobias Mattsson, Lead developer of Blossom, the Spring integration for Magnolia CMS. Tobias answers submitted questions and gives a short introduction to the module and outlines what's new in the 3.0 update.
6. Sr. Software Engineer, Magnolia
Lead developer of Magnolia’s Spring integration
Spring Framework user since 2005
Tobias Mattsson
6
Monday, September 30, 13
7. Blossom 3.0
7
Update for Magnolia 5 series
Requires Magnolia 5.1
Release candidate available
Final release next week
Monday, September 30, 13
14. PAGES CONTAIN 0:n AREAS
14
PAGE
AREA
A
R
E
A
AREA
Monday, September 30, 13
15. PAGES CONTAIN 0:n AREAS
15
PAGE
AREA
A
R
E
A
AREA
AREAS HAVE 0:n COMPONENTS
COMPONENT
COMPONENT
Etiam porta sem malesuada magna mollis
euismod. Duis mollis, est non commodo
luctus, nisi erat porttitor ligula, eget lacinia
odio sem nec elit.
COMPONENT
Etiam porta sem malesuada magna mollis
euismod. Morbi leo risus, porta ac consectetur
ac, vestibulum at eros. Aenean lacinia
bibendum nulla sed consectetur. Aenean eu
leo quam. Pellentesque ornare sem lacinia
quam venenatis vestibulum. Lorem ipsum
dolor sit amet, consectetur adipiscing elit. Sed
posuere consectetur est at lobortis.
C
O
M
P
O
N
E
N
T
Monday, September 30, 13
23. Page Template with Dialog
@Controller
@Template(title="Article", id="myModule:pages/article")
public class ArticleTemplate {
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(cfg.fields.text("title").label("Title"));
}
}
23
Monday, September 30, 13
24. Page Template with Dialog
@Controller
@Template(title="Article", id="myModule:pages/article")
public class ArticleTemplate {
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(cfg.fields.text("title").label("Title"));
}
}
23
Monday, September 30, 13
25. Page Template with Dialog
@Controller
@Template(title="Article", id="myModule:pages/article")
public class ArticleTemplate {
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(cfg.fields.text("title").label("Title"));
}
} <title>${content.title}</title>
<!-- In the view -->
23
Monday, September 30, 13
26. @Controller
@Template(title="Article", id="myModule:pages/article")
public class ArticleTemplate {
@Area("main")
@Controller
public static class MainArea {
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.text("border").label("Border width")
);
Area Template with Dialog 24
Monday, September 30, 13
27. @Controller
@Template(title="Article", id="myModule:pages/article")
public class ArticleTemplate {
@Area("main")
@Controller
public static class MainArea {
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.text("border").label("Border width")
);
Area Template with Dialog 24
Monday, September 30, 13
28. @Controller
@Template(title="Article", id="myModule:pages/article")
public class ArticleTemplate {
@Area("main")
@Controller
public static class MainArea {
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.text("border").label("Border width")
);
Area Template with Dialog 24
<div id="main"
style="border:${content.border}px solid #000">
<h2>${content.heading}</h2>
<c:forEach items="${components}" var="component">
<cms:component content="${component}" />
</c:forEach>
</div> <!-- In the view -->
Monday, September 30, 13
29. Component Template with Dialog
@Controller
@Template(title="Text", id="myModule:components/text")
public class TextComponent {
@RequestMapping("/text")
public String render() {
return "components/text";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.richText("body").label("Text body")
25
Monday, September 30, 13
30. Component Template with Dialog
@Controller
@Template(title="Text", id="myModule:components/text")
public class TextComponent {
@RequestMapping("/text")
public String render() {
return "components/text";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.richText("body").label("Text body")
25
Monday, September 30, 13
31. Component Template with Dialog
@Controller
@Template(title="Text", id="myModule:components/text")
public class TextComponent {
@RequestMapping("/text")
public String render() {
return "components/text";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.richText("body").label("Text body")
25
<h1>${content.heading}</h1>
<p>${cmsfn:decode(content).body}</p>
<!-- In the view -->
Monday, September 30, 13
32. YouTube Video Component
@Controller
@Template(title="YouTube Video", id="myModule:components/youtube")
@TemplateDescription("Embed a YouTube video")
public class YoutubeComponent {
@RequestMapping("/youtube")
public String render(Node node, ModelMap model) throws RepositoryException {
model.put("videoId", node.getProperty("videoId").getString());
return "components/youtube";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("videoId").label("Video ID")
);
}
}
26
Monday, September 30, 13
33. YouTube Video Component
@Controller
@Template(title="YouTube Video", id="myModule:components/youtube")
@TemplateDescription("Embed a YouTube video")
public class YoutubeComponent {
@RequestMapping("/youtube")
public String render(Node node, ModelMap model) throws RepositoryException {
model.put("videoId", node.getProperty("videoId").getString());
return "components/youtube";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("videoId").label("Video ID")
);
}
}
26
Monday, September 30, 13
34. YouTube Video Component
@Controller
@Template(title="YouTube Video", id="myModule:components/youtube")
@TemplateDescription("Embed a YouTube video")
public class YoutubeComponent {
@RequestMapping("/youtube")
public String render(Node node, ModelMap model) throws RepositoryException {
model.put("videoId", node.getProperty("videoId").getString());
return "components/youtube";
}
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("videoId").label("Video ID")
);
}
}
26
<iframe width="100%" height="400" src="//www.youtube.com/
embed/${videoId}" frameborder="0" allowfullscreen></iframe>
<!-- In the view -->
Monday, September 30, 13
35. Dialogs and the Class Hierarchy
public abstract class BasePageTemplate {
@TabFactory("Meta")
public void metaTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("metaAuthor").label("Author"),
cfg.fields.text("metaKeywords").label("Keywords"),
cfg.fields.text("metaDescription").label("Description")
);
}
}
27
Monday, September 30, 13
41. How do I get started on my project?
33
Monday, September 30, 13
42. mvn archetype:generate -DarchetypeCatalog=http://nexus.magnolia-cms.com/
content/groups/public/
choose magnolia-blossom-module-archetype
Define value for property 'groupId': : com.acme
Define value for property 'artifactId': : acme-module
Define value for property 'version': 1.0-SNAPSHOT:
Define value for property 'package': com.acme:
Define value for property 'magnolia-version': : 4.5.11
Define value for property 'module-class-name': : AcmeModule
Define value for property 'module-name': acme-module: acmeModule
http://wiki.magnolia-cms.com/display/WIKI/
Creating+a+new+Blossom+project+using+maven+archetypes
Monday, September 30, 13
43. How would I build a REST interface to my CMS
content using Blossom?
35
Monday, September 30, 13