APACHE SLING & FRIENDS TECH MEETUP BERLIN, 22-24 SEPTEMBER 2014 Dynamic Components using SPA Concepts Andon Sikavica, Bojana Popovska - Netcetera
APACHE SLING & FRIENDS TECH MEETUPBERLIN, 22-24 SEPTEMBER 2014
Dynamic Components using SPA ConceptsAndon Sikavica, Bojana Popovska - Netcetera
adaptTo() 2014 2
Dynamic Components
Dynamic vs Static Components
adaptTo() 2014 3
Initial and form-based components take big chunk of the statics
We spend more than 90% of the time
developing dynamics
Count of Dynamic vs Statics
(in hundreds)
Dynamic Static
Dynamic Component Development
adaptTo() 2014 4
Placeholder for dynamic component in dispatcher think about what you will have in the
dispatcher Request dynamic component via URL
/content/page/_jcr_content/par/comp.dynamic.html
Instruct dispatcher not to cache based on selector #/0042 { /type "deny" /glob "GET
*.dynamic.html*" }
Server Side Includes
adaptTo() 2014 5
Browser Dispatcher AEM
GET Page
return complete Page
GET dynamic component HTML
return component HTML with dynamic
data
Generate HTML
<!--#include virtual= “${c.resourcePath}.dynamic.html}”-->
AJAX
adaptTo() 2014 6
Browser Dispatcher AEM
GET Page
return Page with Placeholders
GET dynamic component HTML
return component HTML with dynamic
data
Generate HTML
Create Markup
$.ajax({ url: '${c.resourcePath}.dynamic.html', success: function(data) { $(“#${c.identifier}").replaceWith(data);}});
Summary
adaptTo() 2014 – https://www.flickr.com/photos/fabrisalvetti/489593502 image by Fabrizio Salvetti
7
Sling Concepts component-path selectors sling:resourceSuperType
Aspect-Oriented Solution
Sling Dynamic Include
What if…
adaptTo() 2014 8
… you have high number of dynamic components on a single page?
… your components need to communicate between themselves and update their state?
… you need to do notifications for the user?
…basically need SPA
Why were the usual approaches Tricky?
adaptTo() 2014 - https://www.flickr.com/photos/15708236@N07/2754478731 photo by jphilipg
9
SSI was meant to be used with page reloads
AJAX works with pre-loaded Markup from
server
adaptTo() 2014 10
Single Page Application
11
SPA Component
adaptTo() 2014
Rendering Script (JSP) Cached, Inherited
Module (JS) Cached, Composition
Controller Handles all dynamic
calls
Table
Abstract
Paging
Sorting
Page Load
adaptTo() 2014 12
Browser Dispatcher AEM
GET Page
return Markup Skeleton
POST for Dynamic Data
return Dynamic Data as JSON
Serialize Data as
JSONRender HTML
using Template with dynamic
data
Technologies
adaptTo() 2014 13
jQuery jQuery Template GSON NEBA (Spring MVC,
AOP)
Benefits
adaptTo() 2014 - https://www.flickr.com/photos/mishism/5370473007 photo by Mish Sukharev
14
Perceived User Experience
Separation of front- and back-end engineering easier development prototype mocked data
adaptTo() 2014 15
Showcase
Rendering Script
adaptTo() 2014 16
<script type=“text/html” id=“scheduleTableTemplate”> <tr> <td data-content=“talkName”></td> <td data-content =“time”></td> </tr></script>
<script type=“text/javascript”> aemdemo.scheduletable.init( ‘http://localhost:4502/bin/mvc.do/scheduletable/getresult’);</script>
$(‘.scheduleTable tbody’).loadTemplate( $(‘#scheduleTableTemplate’), data.talks);
<table class=“scheduleTable”> <th> <td>Talk Name</td> <td>Time</td> </th> <tbody></tbody></table> Template
Static Markup
Initialization script
Inject data
Module
adaptTo() 2014 17
aemdemo.persondetailstable = (function($, paging, sort){ var params; function init (dataUrl){ params.dataUrl = dataUrl; } function getDataByPage (pageNumber) { $.ajax { data : {. . .}, url : params.dataUrl, success : function (data){paging.update (data)}
} } return { init:init }}(jQuery, aemdemo.paging, aemdemo.sort));
Controller
adaptTo() 2014 18
@Controllerpublic class ScheduleTableController { @RequestMapping(value = "/scheduletable/getresult", produces = {"application/json; charset=UTF-8" }, method = POST) @ResponseBody public String getResult(@RequestParam int pageNumber) { ConferenceDay conferenceDay = getDataFromService(); return serializeData(conferenceDay); }}
Identify and Control POSTs
adaptTo() 2014 19
Add Header $.ajaxPrefilter(function (options, originalOptions, jqXHR) { jqXHR.setRequestHeader('X-Request-Source', ‘spa-ajax'); });
Check Handler Servlet servlet = servletResolver.resolveServlet(slingRequest); if (“SlingPostServlet”.equals(servlet.getClass().getSimpleName() && … ) { // ups }
EXCEPTIONHANDLING
adaptTo() 2014 20
https://github.com/andon/spademo
Demo Project
Questions
adaptTo() 2014 21
Thank You!
adaptTo() 2014 22