SlideShare uma empresa Scribd logo
1 de 60
Baixar para ler offline
Blossom Q&A Webinar
1
Monday, September 30, 13
2
Zak Greant
Community Manager, Magnolia
Monday, September 30, 13
Questions?
Use the questions tool
built into the GoToWebinar
client.
3
Monday, September 30, 13
4
forums.magnolia-cms.com
Monday, September 30, 13
#blossomqa
5
Monday, September 30, 13
Sr. Software Engineer, Magnolia
Lead developer of Magnolia’s Spring integration
Spring Framework user since 2005
Tobias Mattsson
6
Monday, September 30, 13
Blossom 3.0
7
Update for Magnolia 5 series
Requires Magnolia 5.1
Release candidate available
Final release next week
Monday, September 30, 13
Magnolia + Spring = Blossom 8
Monday, September 30, 13
@Template
9
Monday, September 30, 13
TEMPLATEREQUEST CONTENT
CMS
10
Monday, September 30, 13
TEMPLATEREQUEST CONTENT
CMS + Blossom
11
CONTROLLER
MODEL
VIEW
Monday, September 30, 13
Page Template
@Controller
@Template(id="myModule:pages/main", title="Main")
public class MainTemplate {
   @RequestMapping("/main")
   public String render(ModelMap model) {
       return "pages/main";
   }
}
12
Monday, September 30, 13
13
PAGE
Monday, September 30, 13
PAGES CONTAIN 0:n AREAS
14
PAGE
AREA
A
R
E
A
AREA
Monday, September 30, 13
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
Area Template
@Controller
@Template(id="myModule:pages/main",title="Main Template")
public class MainTemplate {
   @Controller
   @Area("main")
   public static class MainArea {
       @RequestMapping("/main/mainArea")
       public String render() {
           return "areas/main";
       }
   ...
16
Monday, September 30, 13
Component Template
@Controller
@Template(id="myModule:components/shoppingCart",
         title="Shopping Cart")
@TemplateDescription("Shopping cart")
public class ShoppingCartComponent {
   @RequestMapping("/shoppingCart")
   public String handleRequest() {
       ...
       return "components/shoppingCart";
   }
...
17
Monday, September 30, 13
SERVLET
CONTAINER
RENDERING
FILTER
RENDERING
ENGINE
BLOSSOM
DISPATCHER
SERVLET
CONTROLLER
18
How Blossom Works
Monday, September 30, 13
Blossom 3.0
19
What’s new?
Monday, September 30, 13
20
Dialogs
Monday, September 30, 13
Fluent Builder-style API
@TabFactory("Content")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("Heading"),
cfg.fields.richText("body").label("Text body"),
cfg.fields.websiteLink("categoryLink").label("Link"),
cfg.fields.basicUpload("image").label("Image"),
cfg.fields.checkbox("inlineImage").label("Inline Image")
 );
}
21
Monday, September 30, 13
Blossom 2 Style Dialog
@TabFactory("Content")
public void contentTab(TabBuilder tab) {
DialogEdit dialogEdit = tab.addEdit("title", "Title", "");
dialogEdit.setRequired(true);
dialogEdit.setConfig("i18n", "true");
dialogEdit.setConfig("rows", 5);
}
22
Monday, September 30, 13
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
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
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
@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
@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
@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
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
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
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
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
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
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
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
Input Validation
...
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("name").label("Name").required(),
cfg.fields.text("email").label("Email")⏎
.validator(cfg.validators.email())
);
}
...
28
Monday, September 30, 13
Dynamic Dialog
@Template(id="myModule:components/bookCategory", title="Book category")
@TemplateDescription("A list of books in a given category.")
@Controller
public class BookCategoryComponent {
   @Autowired
   private SalesApplicationWebService service;
   @RequestMapping("/bookcategory")
   public String render(Node content, ModelMap model) throws RepositoryException {
       String category = content.getProperty("category").getString();
       model.put("books", service.getBooksInCategory(category));
       return "components/bookCategory";
   }
@TabFactory("Content")
   public void contentTab(UiConfig cfg, TabBuilder tab) {
       Collection<String> categories = service.getBookCategories();
       tab.fields(
cfg.fields.select("category").label("Category").options(categories)
       );
   }
}
29
Monday, September 30, 13
Dynamic Dialog
@Template(id="myModule:components/bookCategory", title="Book category")
@TemplateDescription("A list of books in a given category.")
@Controller
public class BookCategoryComponent {
   @Autowired
   private SalesApplicationWebService service;
   @RequestMapping("/bookcategory")
   public String render(Node content, ModelMap model) throws RepositoryException {
       String category = content.getProperty("category").getString();
       model.put("books", service.getBooksInCategory(category));
       return "components/bookCategory";
   }
@TabFactory("Content")
   public void contentTab(UiConfig cfg, TabBuilder tab) {
       Collection<String> categories = service.getBookCategories();
       tab.fields(
cfg.fields.select("category").label("Category").options(categories)
       );
   }
}
30
Monday, September 30, 13
Dynamic Dialog
@Template(id="myModule:components/bookCategory", title="Book category")
@TemplateDescription("A list of books in a given category.")
@Controller
public class BookCategoryComponent {
   @Autowired
   private SalesApplicationWebService service;
   @RequestMapping("/bookcategory")
   public String render(Node content, ModelMap model) throws RepositoryException {
       String category = content.getProperty("category").getString();
       model.put("books", service.getBooksInCategory(category));
       return "components/bookCategory";
   }
@TabFactory("Content")
   public void contentTab(UiConfig cfg, TabBuilder tab) {
       Collection<String> categories = service.getBookCategories();
       tab.fields(
cfg.fields.select("category").label("Category").options(categories)
       );
   }
}
31
Monday, September 30, 13
Questions
32
Monday, September 30, 13
How do I get started on my project?
33
Monday, September 30, 13
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
How would I build a REST interface to my CMS
content using Blossom?
35
Monday, September 30, 13
REST servlet in module descriptor
<servlets>
  <servlet>
    <name>rest</name>
    <class>org.springframework.web.servlet.DispatcherServlet</class>
    <mappings>
      <mapping>/rest/*</mapping>
    </mappings>
    <params>
      <param>
        <name>contextConfigLocation</name>
        <value>classpath:/rest-servlet.xml</value>
      </param>
    </params>
  </servlet>
</servlets>
36
Monday, September 30, 13
REST Controller
@Controller
public class ProductsRestController {
@RequestMapping("/products/{productId}")
public Product findProduct(@PathVariable String productId) {
// implementation omitted
}
}
37
Monday, September 30, 13
Can I leverage Magnolia's caching functionality
to improve the performance of my Spring app?
38
Monday, September 30, 13
Influencing caching 39
@Controller
@Template(title="Text", id="myModule:components/text")
public class TextComponent {
@RequestMapping("/text")
public String render(HttpResponse response) {
response.setHeader("Cache-Control", "no-cache");
return "components/text.jsp";
}
}
Monday, September 30, 13
How can I present dialogs in different languages
using Blossom?
40
Monday, September 30, 13
@Controller
@Template(title = "Text", id = "blossomSampleModule:components/text")
@I18nBasename("info.magnolia.blossom.sample.messages")
public class TextComponent {
@TabFactory("textComponent.contentTab.label")
public void contentTab(UiConfig cfg, TabBuilder tab) {
tab.fields(
cfg.fields.text("heading").label("textComponent.contentTab.heading")
);
}
}
41I18n Blossom Dialog
Monday, September 30, 13
/info/magnolia/blossom/sample/messages_en.properties
textComponent.contentTab.label = Content
textComponent.contentTab.heading = Heading
/info/magnolia/blossom/sample/messages_sv.properties
textComponent.contentTab.label = Innehåll
textComponent.contentTab.heading = Rubrik
42I18n Blossom Dialog
Monday, September 30, 13
How do I migrate my existing site to Magnolia/
Blossom?
43
Monday, September 30, 13
How can I integrate Spring Security?
44
Monday, September 30, 13
45
Monday, September 30, 13
How can I dependency inject spring beans into
RenderingModels?
46
Monday, September 30, 13
Autowired RenderingModel
public class MyRenderingModel extends RenderingModelImpl<TemplateDefinition> {
@Autowired
private MyService service;
public MyRenderingModel(ServletContext servletContext, Node content, TemplateDefinition definition, Render
super(content, definition, parent);
WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext);
AutowireCapableBeanFactory beanFactory = wac.getAutowireCapableBeanFactory();
beanFactory.autowireBean(this);
}
47
Monday, September 30, 13
Autowired RenderingModel
public class MyRenderingModel extends AbstractAutowiredRenderingModel<TemplateDefinition> {
@Autowired
private MyService service;
public MyRenderingModel(ServletContext servletContext, Node content, TemplateDefinition definition, Render
super(content, definition, parent, servletContext);
}
48
Monday, September 30, 13
More questions?
49
Monday, September 30, 13
Magnolia + Spring = Blossom 50
Monday, September 30, 13
Thank You!
51
Monday, September 30, 13
52
magnolia-cms.com/spring
Monday, September 30, 13

Mais conteúdo relacionado

Último

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Scriptwesley chun
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodJuan lago vázquez
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyKhushali Kathiriya
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...Neo4j
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CVKhem
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...apidays
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FMESafe Software
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘RTylerCroy
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)Gabriella Davis
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoffsammart93
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024The Digital Insurer
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsRoshan Dwivedi
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesBoston Institute of Analytics
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century educationjfdjdjcjdnsjd
 

Último (20)

Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin WoodPolkadot JAM Slides - Token2049 - By Dr. Gavin Wood
Polkadot JAM Slides - Token2049 - By Dr. Gavin Wood
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...Workshop - Best of Both Worlds_ Combine  KG and Vector search for  enhanced R...
Workshop - Best of Both Worlds_ Combine KG and Vector search for enhanced R...
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
Bajaj Allianz Life Insurance Company - Insurer Innovation Award 2024
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024Axa Assurance Maroc - Insurer Innovation Award 2024
Axa Assurance Maroc - Insurer Innovation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live StreamsTop 5 Benefits OF Using Muvi Live Paywall For Live Streams
Top 5 Benefits OF Using Muvi Live Paywall For Live Streams
 
HTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation StrategiesHTML Injection Attacks: Impact and Mitigation Strategies
HTML Injection Attacks: Impact and Mitigation Strategies
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 

Destaque

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Destaque (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

Blossom Q&A Webinar

  • 1. Blossom Q&A Webinar 1 Monday, September 30, 13
  • 2. 2 Zak Greant Community Manager, Magnolia Monday, September 30, 13
  • 3. Questions? Use the questions tool built into the GoToWebinar client. 3 Monday, September 30, 13
  • 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
  • 8. Magnolia + Spring = Blossom 8 Monday, September 30, 13
  • 11. TEMPLATEREQUEST CONTENT CMS + Blossom 11 CONTROLLER MODEL VIEW Monday, September 30, 13
  • 12. Page Template @Controller @Template(id="myModule:pages/main", title="Main") public class MainTemplate {    @RequestMapping("/main")    public String render(ModelMap model) {        return "pages/main";    } } 12 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
  • 16. Area Template @Controller @Template(id="myModule:pages/main",title="Main Template") public class MainTemplate {    @Controller    @Area("main")    public static class MainArea {        @RequestMapping("/main/mainArea")        public String render() {            return "areas/main";        }    ... 16 Monday, September 30, 13
  • 17. Component Template @Controller @Template(id="myModule:components/shoppingCart",          title="Shopping Cart") @TemplateDescription("Shopping cart") public class ShoppingCartComponent {    @RequestMapping("/shoppingCart")    public String handleRequest() {        ...        return "components/shoppingCart";    } ... 17 Monday, September 30, 13
  • 21. Fluent Builder-style API @TabFactory("Content") public void contentTab(UiConfig cfg, TabBuilder tab) { tab.fields( cfg.fields.text("heading").label("Heading"), cfg.fields.richText("body").label("Text body"), cfg.fields.websiteLink("categoryLink").label("Link"), cfg.fields.basicUpload("image").label("Image"), cfg.fields.checkbox("inlineImage").label("Inline Image")  ); } 21 Monday, September 30, 13
  • 22. Blossom 2 Style Dialog @TabFactory("Content") public void contentTab(TabBuilder tab) { DialogEdit dialogEdit = tab.addEdit("title", "Title", ""); dialogEdit.setRequired(true); dialogEdit.setConfig("i18n", "true"); dialogEdit.setConfig("rows", 5); } 22 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
  • 36. Input Validation ... public void contentTab(UiConfig cfg, TabBuilder tab) { tab.fields( cfg.fields.text("name").label("Name").required(), cfg.fields.text("email").label("Email")⏎ .validator(cfg.validators.email()) ); } ... 28 Monday, September 30, 13
  • 37. Dynamic Dialog @Template(id="myModule:components/bookCategory", title="Book category") @TemplateDescription("A list of books in a given category.") @Controller public class BookCategoryComponent {    @Autowired    private SalesApplicationWebService service;    @RequestMapping("/bookcategory")    public String render(Node content, ModelMap model) throws RepositoryException {        String category = content.getProperty("category").getString();        model.put("books", service.getBooksInCategory(category));        return "components/bookCategory";    } @TabFactory("Content")    public void contentTab(UiConfig cfg, TabBuilder tab) {        Collection<String> categories = service.getBookCategories();        tab.fields( cfg.fields.select("category").label("Category").options(categories)        );    } } 29 Monday, September 30, 13
  • 38. Dynamic Dialog @Template(id="myModule:components/bookCategory", title="Book category") @TemplateDescription("A list of books in a given category.") @Controller public class BookCategoryComponent {    @Autowired    private SalesApplicationWebService service;    @RequestMapping("/bookcategory")    public String render(Node content, ModelMap model) throws RepositoryException {        String category = content.getProperty("category").getString();        model.put("books", service.getBooksInCategory(category));        return "components/bookCategory";    } @TabFactory("Content")    public void contentTab(UiConfig cfg, TabBuilder tab) {        Collection<String> categories = service.getBookCategories();        tab.fields( cfg.fields.select("category").label("Category").options(categories)        );    } } 30 Monday, September 30, 13
  • 39. Dynamic Dialog @Template(id="myModule:components/bookCategory", title="Book category") @TemplateDescription("A list of books in a given category.") @Controller public class BookCategoryComponent {    @Autowired    private SalesApplicationWebService service;    @RequestMapping("/bookcategory")    public String render(Node content, ModelMap model) throws RepositoryException {        String category = content.getProperty("category").getString();        model.put("books", service.getBooksInCategory(category));        return "components/bookCategory";    } @TabFactory("Content")    public void contentTab(UiConfig cfg, TabBuilder tab) {        Collection<String> categories = service.getBookCategories();        tab.fields( cfg.fields.select("category").label("Category").options(categories)        );    } } 31 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
  • 44. REST servlet in module descriptor <servlets>   <servlet>     <name>rest</name>     <class>org.springframework.web.servlet.DispatcherServlet</class>     <mappings>       <mapping>/rest/*</mapping>     </mappings>     <params>       <param>         <name>contextConfigLocation</name>         <value>classpath:/rest-servlet.xml</value>       </param>     </params>   </servlet> </servlets> 36 Monday, September 30, 13
  • 45. REST Controller @Controller public class ProductsRestController { @RequestMapping("/products/{productId}") public Product findProduct(@PathVariable String productId) { // implementation omitted } } 37 Monday, September 30, 13
  • 46. Can I leverage Magnolia's caching functionality to improve the performance of my Spring app? 38 Monday, September 30, 13
  • 47. Influencing caching 39 @Controller @Template(title="Text", id="myModule:components/text") public class TextComponent { @RequestMapping("/text") public String render(HttpResponse response) { response.setHeader("Cache-Control", "no-cache"); return "components/text.jsp"; } } Monday, September 30, 13
  • 48. How can I present dialogs in different languages using Blossom? 40 Monday, September 30, 13
  • 49. @Controller @Template(title = "Text", id = "blossomSampleModule:components/text") @I18nBasename("info.magnolia.blossom.sample.messages") public class TextComponent { @TabFactory("textComponent.contentTab.label") public void contentTab(UiConfig cfg, TabBuilder tab) { tab.fields( cfg.fields.text("heading").label("textComponent.contentTab.heading") ); } } 41I18n Blossom Dialog Monday, September 30, 13
  • 50. /info/magnolia/blossom/sample/messages_en.properties textComponent.contentTab.label = Content textComponent.contentTab.heading = Heading /info/magnolia/blossom/sample/messages_sv.properties textComponent.contentTab.label = Innehåll textComponent.contentTab.heading = Rubrik 42I18n Blossom Dialog Monday, September 30, 13
  • 51. How do I migrate my existing site to Magnolia/ Blossom? 43 Monday, September 30, 13
  • 52. How can I integrate Spring Security? 44 Monday, September 30, 13
  • 54. How can I dependency inject spring beans into RenderingModels? 46 Monday, September 30, 13
  • 55. Autowired RenderingModel public class MyRenderingModel extends RenderingModelImpl<TemplateDefinition> { @Autowired private MyService service; public MyRenderingModel(ServletContext servletContext, Node content, TemplateDefinition definition, Render super(content, definition, parent); WebApplicationContext wac = WebApplicationContextUtils.getWebApplicationContext(servletContext); AutowireCapableBeanFactory beanFactory = wac.getAutowireCapableBeanFactory(); beanFactory.autowireBean(this); } 47 Monday, September 30, 13
  • 56. Autowired RenderingModel public class MyRenderingModel extends AbstractAutowiredRenderingModel<TemplateDefinition> { @Autowired private MyService service; public MyRenderingModel(ServletContext servletContext, Node content, TemplateDefinition definition, Render super(content, definition, parent, servletContext); } 48 Monday, September 30, 13
  • 58. Magnolia + Spring = Blossom 50 Monday, September 30, 13