Drupal on the Big Screen
Decoupled Drupal Powering an Interactive Touchscreen Kiosk
Brian Reese
brian.reese@gmail.com
github.com/darkcody
brian-reese.com
senior developer @ acquia
What we'll cover
- A little background on headless & decoupled Drupal
- A case study on a decoupled drupal implementation powering a kiosk
- A quick demo showing how easy it can be to get started
A Little Background
1.
on decoupling drupal
Rendered Pages
CMS
Custom Front End
CMS
Content Creation Tools
Content Repository
Presentation Logic
(renders raw data into pages)
Content Creation Tools
Content Repository
Raw Data
Traditional
Headless/Decoupled
Rendered Page
CMS
Content Creation Tools
Content Repository
API
Progressively Decoupled
Component
Component
Presentation Logic
Custom Front End
CMS
(renders raw data into pages)
Content Creation Tools
Content Repository
Raw Data
Fully Decoupled
Why you might Choose a Decoupled architechture?
- Flexibility in your presentation layer
- Increased speed/responsiveness
- More interactive interfaces
- Front-end devs don't need to know Drupal
Some Possible Downsides
- Introduces more complexity
- Lose a lot of out-of-the-box drupal
- Can be more difficult for small or single-person teams
A Case Study
2.
building a kiosk
Client Checklist:
-
User friendly
-
Touch screen
-
Various Social media integrations
-
Use whatever tech you want*
-
Concert details & Musician Bios
just make it cool
(Magical Unicorn)
(Two-headed monster)
Application + APIs
AngularJS
Drupal 7
Youtube
Google Maps + Calendar
Why AngularJS?
- Excellent DOM Manipulation framework
- Flexibile Services
- Modular components
- Familiarity
Why Drupal?
- Excellent CMS
- Easy REST services
- Familiarity
Drupal
Home Screen
Ensembles
Photo Gallery
Video Gallery
Calendar
Map
Ensemble Members
Ensemble Detail
Member Bios
Facebook Graph API
Youtube player API
Google Calendar / .ics
Google Maps
Google Geocoding API
Drupal
Home Screen
Ensembles
Photo Gallery
Video Gallery
Calendar
Map
Ensemble Members
Ensemble Detail
Member Bios
Facebook Graph API
Youtube player API
Google Calendar / .ics
Google Maps
Google Geocoding API
Drupal
Home Screen
Ensembles
Photo Gallery
Video Gallery
Calendar
Map
Ensemble Members
Ensemble Detail
Member Bios
Facebook Graph API
Youtube player API
Google Calendar / .ics
Google Maps
Google Geocoding API
A Quick Demo
3.
Drupal Modules to Enable:
REST
REST UI (contrib)
Serialization
HTTP Basic Authentication
RESTful Web Services are available in d8 core
https://drupalize.me/blog/201401/introduction-restful-web-services-drupal-8
Great introduction to REST in d8:
Drupal
Home Screen
Ensembles
Photo Gallery
Video Gallery
Calendar
Map
Ensemble Members
Ensemble Detail
Member Bios
Facebook Graph API
Youtube player API
Google Calendar / .ics
Google Maps
Google Geocoding API
angular.module('calendar.services', [])
.provider('CalendarConfiguration', function CalendarConfigurationProvider (){
this.addGoogleCalendar = function(calendarLabel, calendarId, apiKey){
// ...Store config details for a google calendar.
};
this.addIcalCalendar = function(calendarLabel, calendarId, apiKey){
// ...Store config details for an Ical
};
});
Creating an angular service for calendar config
separate methods for google & ical
angular.module( 'kiosk', [
'calendar.services'
])
.config( function kioskConfig( CalendarConfigurationProvider ){
CalendarConfigurationProvider.addIcalCalendar('Sessions', 'http://badcampdemo.local/sessions');
CalendarConfigurationProvider.addGoogleCalendar('Bay Area Events', 'foo@group.calendar.google.com');
})
Allows one-line configuration for each calendar source
note both ical and google calendars used above
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:web test events
X-WR-TIMEZONE:America/New_York
X-WR-CALDESC:A test calendar for importing and exporting events
BEGIN:VEVENT
DTSTART:20161024T223000Z
DTEND:20161025T015500Z
DTSTAMP:20161022T182226Z
UID:AEE7890B-17D0-4598-BDED-9C27A79E1901
URL:message://%3C119004230.1476213003399.JavaMail.dets%40ny-dets-002%3E?c=1
476213006&k=%7CflightF9%5C%7CDEN%5C%7CDCA%5C%7C720%5C%7C
CREATED:20161012T184448Z
DESCRIPTION:Brian Reginald Reese
LAST-MODIFIED:20161012T184448Z
LOCATION:Denver International Airport
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Flight: F9 720 from DEN to DCA
TRANSP:OPAQUE
X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-RADIUS=0;X-TITLE=Denver Inter
national Airport:geo:39.861698,-104.672996
X-APPLE-SUGGESTION-INFO-CHANGED-FIELDS:0
X-APPLE-SUGGESTION-INFO-CHANGES-ACKNOWLEDGED:FALSE
X-APPLE-SUGGESTION-INFO-OPAQUE-KEY:|flightF9\\|DEN\\|DCA\\|720\\|
X-APPLE-SUGGESTION-INFO-UNIQUE-KEY:|2|\\|flightF9\\\\\\|DEN\\\\\\|DCA\\\\\\
|720\\\\\\||\\|5\\|\\\\\\|4371109B-D5A3-47B0-953E-41271774D06A\\\\\\|<11900
4230.1476213003399.JavaMail.dets@ny-dets-002>
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:DISABLED
END:VEVENT
END:VCALENDAR
A google calendar feed
BEGIN:VCALENDAR
VERSION:2.0
METHOD:PUBLISH
X-WR-CALNAME;VALUE=TEXT:
PRODID:-//Drupal iCal API//EN
BEGIN:VEVENT
SUMMARY: Brian demos a kiosk
DTSTART:20161023T143907Z
CREATED:20161021T233907Z
LOCATION: UC Berkeley, Berkeley CA
DESCRIPTION: Lorem ipsum dolor sit amet, consectetur adipiscing elit...
END:VEVENT
END:VCALENDAR
My drupal ical feed
BEGIN:VCALENDAR
PRODID:-//Google Inc//Google Calendar 70.9054//EN
VERSION:2.0
CALSCALE:GREGORIAN
METHOD:PUBLISH
X-WR-CALNAME:web test events
X-WR-TIMEZONE:America/New_York
X-WR-CALDESC:A test calendar for importing and exporting events
BEGIN:VEVENT
DTSTART:20161024T223000Z
DTEND:20161025T015500Z
DTSTAMP:20161022T182226Z
UID:AEE7890B-17D0-4598-BDED-9C27A79E1901
URL:message://%3C119004230.1476213003399.JavaMail.dets%40ny-dets-002%3E?c=1
476213006&k=%7CflightF9%5C%7CDEN%5C%7CDCA%5C%7C720%5C%7C
CREATED:20161012T184448Z
DESCRIPTION:Brian Reginald Reese
LAST-MODIFIED:20161012T184448Z
LOCATION:Denver International Airport
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:Flight: F9 720 from DEN to DCA
TRANSP:OPAQUE
X-APPLE-STRUCTURED-LOCATION;VALUE=URI;X-APPLE-RADIUS=0;X-TITLE=Denver Inter
national Airport:geo:39.861698,-104.672996
X-APPLE-SUGGESTION-INFO-CHANGED-FIELDS:0
X-APPLE-SUGGESTION-INFO-CHANGES-ACKNOWLEDGED:FALSE
X-APPLE-SUGGESTION-INFO-OPAQUE-KEY:|flightF9\\|DEN\\|DCA\\|720\\|
X-APPLE-SUGGESTION-INFO-UNIQUE-KEY:|2|\\|flightF9\\\\\\|DEN\\\\\\|DCA\\\\\\
|720\\\\\\||\\|5\\|\\\\\\|4371109B-D5A3-47B0-953E-41271774D06A\\\\\\|<11900
4230.1476213003399.JavaMail.dets@ny-dets-002>
X-APPLE-TRAVEL-ADVISORY-BEHAVIOR:DISABLED
END:VEVENT
END:VCALENDAR
A google calendar feed
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//AFWebCMS//Omnitech Inc.//EN
BEGIN:VEVENT
DTSTART:20160504T120000Z
DEND:20160504T090000Z
SUMMARY:12:10-12:45 p.m.
St. John's Church at Lafayette Square
1525 H St. NW
Washington, DC 20005
Join us for an afternoon of music for string orchestra and soloists. We will be performing J.S. Bach's Brandenburg Concerto No. 5 in D Major, BWV 1050 and Friedrich Robert Volkmann's Serenade No. 2 in F Major, Op. 63. Soloist for the Brandenburg concerto are Chief Master Sergeant Stacy Ascione, flute; Master Sergeant Cleveland Chandler, violin; and Brandon Straub, harpsichord.
END:VEVENT
END:VCALENDAR
calendar from legacy cms
angular.module('calendar.services', [])
.provider('CalendarConfiguration', function CalendarConfigurationProvider (){
// ...
})
.service( 'calendarService', ['$http', '$q', 'CalendarConfiguration'],
function($http, $q, CalendarConfiguration) {
var fetchGcalEvents = function() {
// Fetch calendar data using $http and parse relevant details
// Return a promise.
}
var fetchIcalEvents = function() {
// Fetch calendar data using $http and parse relevant details
// Return a promise.
};
});
In our angular calendar services module, we define methods to fetch each type of feed
// ...
var fetchEvents = function(){
CalendarConfiguration.getGoogleCalendars().forEach(function(){
calendarEvents.push(fetchGcalEvents());
});
CalendarConfiguration.getIcalCalendars().forEach(function(){
calendarEvents.push(fetchIcalEvents());
});
$q.all(calendarEvents).then(function(promiseResolves){
// Combine our resolves.
var data = [];
promiseResolves.forEach(function(promiseResolve){
data.concat(promiseResolve);
});
// resolve the original promise.
promiseObj.resolve(data);
});
};
And then we write a wrapper to resolve all the data at the same time
angular.module( 'kiosk', [
'calendar.services'
])
.config( function kioskConfig( CalendarConfigurationProvider ){
CalendarConfigurationProvider.addIcalCalendar('Sessions', 'http://badcampdemo.local/sessions');
CalendarConfigurationProvider.addIcalCalendar('Bay Area Events', 'foo@group.calendar.google.com');
})
.controller( 'KioskCtrl', function KioskCtrl($scope, calendarService) {
calendarService.fetchEvents().then(function(events){
$scope.events = events;
})
});
Allows us to populate $scope with a an array of all our events
Questions?
Brian Reese
brian.reese@gmail.com
github.com/darkcody
brian-reese.com
senior developer @ acquia
Drupal on the big screen
By Brian Reese
Drupal on the big screen
A look at decoupled drupal powering an interactive touchscreen kiosk
- 1,272