making sling grunt · apache sling & friends tech meetup berlin, 28-30 september 2015 making...

44
APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling Philip Hornig (Publicis Pixelpark), Michael Sunaric (Netcentric)

Upload: others

Post on 23-Aug-2020

10 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015

Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Philip Hornig (Publicis Pixelpark), Michael Sunaric (Netcentric)

Page 2: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Topics

adaptTo() 2015 2

Modern front-end development and why we need it. How to integrate modern front-end development

with the Sling development stack. The tools necessary to achieve the integration.

Page 3: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

adaptTo() 2015 3

Modern Front-End Development

Page 4: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Complexity is increasing

adaptTo() 2015 4

Complex layouts and responsive design Client side apps Modular and object oriented design Automated testing Documentation

Page 5: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Agile development

adaptTo() 2015 5

Rapid prototyping Design in HTML

Prototyping engine with node.js, express.js

Page 6: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Setup

adaptTo() 2015 6

Scaffolding Yeoman, Middleman, …

Libraries jQuery, Bootstrap, Modernizr, Bourbon

Frameworks Ember.js, AngularJS, Backbone.js,

ExtJS, Dojo, ...

Page 7: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Develop

adaptTo() 2015 7

Prototype Node.js, Express

Watch CSS (Sass, Less, Stylus) Javascript (CoffeeScript, TypeScript, ECMAScript 6) HTML (Jade, Haml, Handlebars) Lint

CSS (csslint, sasslint, styluslint) Javascript (jshint, jscs)

Refresh LiveReload

Page 8: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Test

adaptTo() 2015 8

Function PhantomJS, CasperJS,

Selenium

Form Selenium, BackstopJS

Page 9: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Build

adaptTo() 2015 9

1. Code linting 2. Compile 3. Unit tests 4. Concatenate 5. Minify 6. Generate icons/iconfonts

7. Optimize images 8. Measure performance 9. Prototype 10. Integration tests 11. Deploy

Page 10: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Build Tools and Dependency Mgmt.

adaptTo() 2015 10

NPM, Bower, Gulp, Grunt, Broccoli

Page 11: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Gruntfile.js

adaptTo() 2015 11

module.exports = function (grunt) {

"use strict";

require("load-grunt-config")(grunt, {

init: true,

data: {

assetsSrc: "assets",

assetsDist: "src/main/resources/apps/demo/assets"

}

});

grunt.registerTask("default", ["clean", "bowercopy", "scss", "js", "jsonlint:models"]);

grunt.registerTask("dev", ["default", "express:dev", "watch"]);

grunt.registerTask("scss", ["scsslint", "sass"]);

grunt.registerTask("js", ["jscs", "jshint", "concat", "uglify"]);

};

Page 12: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Sass Task

adaptTo() 2015 12

module.exports = function (grunt) {

"use strict";

return {

options: {

quiet: true,

sourcemap: "inline",

unixNewlines: true,

trace: true

},

all: {

options: {

style: "expanded"

},

src: "<%= assetsSrc %>/scss/style.scss",

dest: "<%= assetsDist %>/css/style.css"

}

};

};

Page 13: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Working with Grunt

adaptTo() 2015 13

Page 14: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

adaptTo() 2015 14

How to integrate with backend development

Page 15: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

How integration used to be

adaptTo() 2015 15

A) Code duplication Front-end delivers HTML prototype, back-end developers recreate templates in back-end (e.g. jsp)

B) Back-end tool chain only Front-end developer works with back-end tools/development environment to create front-end code.

Page 16: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Pitfalls of “code duplication”

adaptTo() 2015 16

Extra work, more code to maintain, error prone Eventually front-end code and back-end code

diverge.

Page 17: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Pitfalls of “back-end tool chain only”

adaptTo() 2015 17

Not compatible with modern front-end stack Each discipline requires more specialized

knowledge. Usage of full back-end stack for front-end

development is time consuming.

Page 18: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

How we would like the process to be like

adaptTo() 2015 18

Planning

Model

Development

Java Code

HTML, CSS, JS

Sling

Integration

Back-End

Front-End

Test-Driven

Prototyping

Page 19: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

How we would like the process to be like

adaptTo() 2015 19

Planning

Model

Development

Java Code

HTML, CSS, JS

Sling

Integration

Back-End

Front-End

Test-Driven

Prototyping

Page 20: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Planning Phase

adaptTo() 2015 20

The interface between front-end and back-end is the data model

The data model is defined in a JSON file The JSON file serves as documentation of the

interface

Page 21: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

How we would like the process to be like

adaptTo() 2015 21

Planning

Model

Development

Java Code

HTML, CSS, JS

Sling

Integration

Back-End

Front-End

Test-Driven

Prototyping

Page 22: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Development Phase

adaptTo() 2015 22

Now front-end and back-end development can start in parallel

The front-end uses the JSON file in development for the HTML prototype

The back-end develops test-driven against the data model

Page 23: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

How we would like the process to be like

adaptTo() 2015 23

Planning

Model

Development

Java Code

HTML, CSS, JS

Sling

Integration

Back-End

Front-End

Test-Driven

Prototyping

Page 24: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Integration Phase

adaptTo() 2015 24

In Sling front-end and back-end code is deployed and works together seamlessly.

Page 25: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

The Crux

adaptTo() 2015 25

Touchpoint between front-end and back-end is the template engine …which merges the template delivered by the front-end and the data model delivered by the back-end

We need a common template engine!

Page 26: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Unified Template Source

adaptTo() 2015 26

Template development is front-end driven. Templates must be part of the front-end stack. Templates must contain only presentation logic. Templates must be renderable in Sling.

Page 27: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Our solution

adaptTo() 2015 27

Front-end stack with Handlebars as template language

Sling uses a Handlebars Sling Script Engine

Page 29: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

AEM Social Component Framework

adaptTo() 2015 29

Closed source, support for our purpose unclear. API and implementation is specific to Social

Communities.

Page 30: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Handlebars Script Engine by Ian Boston

adaptTo() 2015 30

Uses JCR structure as data model. For complex applications, the JCR structure will not

match the presentation model.

Page 31: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

adaptTo() 2015 31

Handlebars Sling Script Engine with Context Generators

Page 32: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Script Engine with Context Generators

adaptTo() 2015 32

Add “context generators”. Context generators create a specific presentation

model for each template.

Page 33: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Script Engine with Context Generators - 2

adaptTo() 2015 33

We implemented two context generators: SimpleContextGenerator

Exposes JCR structure as model

PresenterContextGenerator

Page 34: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

PresenterContextGenerator

adaptTo() 2015 34

Delegates model generation to a Sling Model bean. Bean is assigned by Presenter annotation to a

sling:resourceType.

Page 35: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Template

adaptTo() 2015 35

Handlebars template

<!doctype html>

<html lang="en">

<head>

<title>{{title}}</title>

<link rel="stylesheet" href="/demo/assets/css/style.css">

</head>

<body>

{{include this template="body"}}

{{include this path="footer" resourceType="demo/components/modules/footer"}}

</body>

</html>

Page 36: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Model

adaptTo() 2015 36

Provide presentation model using Sling Models

@Model(adaptables = Resource.class)

@Presenter(resourceTypes = {"demo/components/page"})

public class PagePresenter {

@ValueMapValue

@XSSProtection(strategy = XSSProtection.Strategy.HTML_FILTER)

private String title;

public String getTitle() {

return title + " presented by PagePresenter";

}

}

Page 37: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Model generation

adaptTo() 2015 37

Find the right Presenter and convert it to a Map

public Map<String, Object> createModel(ScriptContext scriptContext) {

Resource resource = new

ScriptContextAdapter(scriptContext).getResource();

String resourceType = resource.getResourceType();

Class<?> presenterType =

presenterBundleListener.getPresenters().get(resourceType);

Object presenter = null;

if (presenterType != null) {

presenter = resource.adaptTo(presenterType);

}

return beanToMapSerializer.convertToMap(presenter);

}

Page 38: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Server-Side Rendering

adaptTo() 2015 38

Render the template with Handlebars.java

public Object eval(Reader templateReader, ScriptContext scriptContext)…{

Handlebars handlebars = new Handlebars();

Template template = getTemplate(templateReader, scriptContext,

handlebars);

Context context = createContext(scriptContext);

if (context != null) {

template.apply(context, scriptContext.getWriter());

}

Page 39: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Features

adaptTo() 2015 39

Handlebars.java HTML-escapes by default. Additional, customizable XSS protection by

XSSProtection annotation. Template languages can be mixed (e.g. body.hbs

may include parsys.jsp).

Page 41: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Outlook

adaptTo() 2015 41

Adding additional Handlebars helper via a Service Factory

AEM helper plugin (i18N, WCMMode) Presenter lookup by Sling selectors

Page 42: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

adaptTo() 2015 42

Thank you

Page 44: Making Sling Grunt · APACHE SLING & FRIENDS TECH MEETUP BERLIN, 28-30 SEPTEMBER 2015 Making Sling Grunt Or How to Integrate Modern Front-End Development with Sling

Contact

adaptTo() 2015 44

Michael Sunaric, Netcentric [email protected] Philip Hornig, Publicis Pixelpark [email protected]