SlideShare ist ein Scribd-Unternehmen logo
1 von 29
Mastering the Sling Rewriter
Justin Edelson
AEM Evangelist
© 2015 Adobe Systems Incorporated. All Rights Reserved. 2
© 2015 Adobe Systems Incorporated. All Rights Reserved. 3
• Sling Rewriter an Apache Sling module included in AEM.
• Performs transformations of rendered content (typically
HTML)
• Doesn’t know anything about your components
• Pipeline-orientated
• Based on Simple API for XML (SAX)
What is the Sling Rewriter?
© 2015 Adobe Systems Incorporated. All Rights Reserved. 4
No.
Sling Rewriter is about rewriting the (HTML) output.
mod_rewrite is about rewriting the requesting URL.
There is an Apache module, mod_ext_filter, which can be used
for output rewriting.
Is Sling Rewriter related to mod_rewrite?
© 2015 Adobe Systems Incorporated. All Rights Reserved. 5
Transformer
Rewriter Pipeline
Output
Content
(HTML, XML)
Output
Content
(HTML, XML)
Generator
SAX
Events
SAX
Events
Transformer SerializerTransformer
Pipeline
© 2015 Adobe Systems Incorporated. All Rights Reserved. 6
Stored in the repository.
Always /apps/SOMETHING/config/rewriter
Defines when the pipeline is executed
Defines how the pipeline is composed
Rewriter Pipeline Configurations
© 2015 Adobe Systems Incorporated. All Rights Reserved. 7
contentTypes – Response Content Type (e.g. text/html)
extensions – Request Extension (e.g. html)
resourceTypes – Resolved Resource Type
selectors – Request selectors (soon; not in AEM 6.1)
paths – Path prefixes
enabled – true/false
order – highest wins
Enablement Options
All are optional
© 2015 Adobe Systems Incorporated. All Rights Reserved. 8
generatorType
transformerTypes
serializerType
Pipeline Options
@Component @Service
@Property(name = "pipeline.type”,
value = "xml-generator")
public class XMLParserGeneratorFactory
implements GeneratorFactory { }
@Component @Service
@Property(name = "pipeline.type",
value = "versioned-clientlibs")
public class VersionedClientlibsTransformerFactory
implements TransformerFactory { }
@Component @Service
@Property(name = "pipeline.type”,
value = "xml-serializer")
public class PlainXMLSerializerFactory
implements SerializerFactory { }
© 2015 Adobe Systems Incorporated. All Rights Reserved. 9
Nodes named <component-type>-<component-name>
Only one defined property - component-optional
Everything else is up to the particular component to define
Pipeline Element Configuration
© 2015 Adobe Systems Incorporated. All Rights Reserved. 10
Implement two interfaces
@Component @Service
@Property(name = "pipeline.type”,
value = ”mytrans")
public class MyTransformerFactory
implements TransformerFactory {
public Transformer createTransformer() {
return new MyTransformer();
}
private class MyTransformer
implements Transformer {
…
}
}
Creating your own Transformer
© 2015 Adobe Systems Incorporated. All Rights Reserved. 11
Transformers can be declared as global.
@Component @Service
@Property(name="pipeline.mode",
value="global")
public class MyEvilTransformer
implements TransformerFactory {}
This is a bad idea.
Don’t do it.
“global” Transformers
© 2015 Adobe Systems Incorporated. All Rights Reserved. 12
public void startElement(String namespaceURI, String localName,
String qName, Attributes atts) {
nextHandler.startElement(namespaceURI, localName,
qName, rebuildAttributes(localName, atts));
}
private Attributes rebuildAttributes(String elementName, Attributes attrs) {
if (“a”.equals(elementName)) {
AttributesImpl newAttrs = new AttributesImpl(attrs);
…
return newAttrs;
} else {
return attrs;
}
}
Creating your own Transformer
© 2015 Adobe Systems Incorporated. All Rights Reserved. 13
<iframe width="420" height="315"
src=“https://www.youtube.com/embed/QfvFWSQQ_0M”
frameborder="0" allowfullscreen>
</iframe>
<div class="youtube-container">
<iframe width="420" height="315"
src=“https://www.youtube.com/embed/QfvFWSQQ_0M”
frameborder="0" allowfullscreen class=“youtube-wrapped”>
</iframe>
</div>
Transformer Use Case
Wrapping YouTube Embedded IFrames
© 2015 Adobe Systems Incorporated. All Rights Reserved. 14
public void startElement(String uri, String localName, String qName, Attributes atts) {
if ("iframe".equals(localName) && needsWrapping(atts)) {
startWrapper();
needToUnwrap = true;
AttributesImpl newAtts = new AttributesImpl();
newAtts.setAttributes(atts);
newAtts.addAttribute("", "class", "class", "CDATA", "youtube-wrapped");
nextHandler.startElement(uri, localName, qName, newAtts);
} else {
nextHandler.startElement(uri, localName, qName, atts);
}
}
public void endElement(String uri, String localName, String qName) {
nextHandler.endElement(uri, localName, qName);
if (needToUnwrap && localName.equals("iframe")) {
endWrapper();
needToUnwrap = false;
}
}
Adding YouTube Wrapper
© 2015 Adobe Systems Incorporated. All Rights Reserved. 15
boolean needsWrapping(Attributes atts) {
final String src = atts.getValue("src");
if (src == null) {
return false;
}
if (src.contains("youtube")) {
final String classAttr = atts.getValue("class");
if (classAttr == null) {
return true;
} else if (classAttr.indexOf("youtube-wrapped") > -1) {
return false;
} else {
return true;
}
}
return false;
}
Adding YouTube Wrapper
© 2015 Adobe Systems Incorporated. All Rights Reserved. 16
void endWrapper(){
nextHandler.endElement("", "div", "div");
}
void startWrapper(){
AttributesImpl newAtts = new AttributesImpl();
newAtts.addAttribute("", "class", "class", "CDATA”,
"youtube-container");
nextHandler.startElement("", "div", "div", newAtts);
}
Adding YouTube Wrapper
© 2015 Adobe Systems Incorporated. All Rights Reserved. 17
• AEM’s HTML parser ignores <iframe> by default.
• Need to adjust the configuration
• With a node named generator-htmlparser
BUT…
© 2015 Adobe Systems Incorporated. All Rights Reserved. 18
The init() method
© 2015 Adobe Systems Incorporated. All Rights Reserved. 19
The characters() method is hard…
<div>foo</div>
characters(['f','o','o'], 0, 2);
characters(['f'], 0, 1);
characters(['o'], 0, 1);
characters(['o'], 0, 1);
characters(['>','f'], 1, 2);
characters(['o', 'o'], 0, 2);
The characters() method
“SAX parsers may
return all contiguous
character data in a
single chunk, or they
may split it into
several chunks.“
© 2015 Adobe Systems Incorporated. All Rights Reserved. 20
For simple manipulations:
public void characters(char ch[],int start, int length) {
String str = new String(ch, start, length);
str = str.toUpperCase();
nextHandler.characters(str.toCharArray(), 0, length);
}
The characters() method
© 2015 Adobe Systems Incorporated. All Rights Reserved. 21
For complex manipulations:
public void startElement(String uri, String localName, String qName,
Attributes atts) {
if (isSpecialElement(localName, atts) {
collectingCharacters = true;
buffer = new StringBuilder();
}
nextHandler.startElement(uri, localName, qName, atts);
}
public void characters(char[] ch, int start, int length) {
if (collectingCharacters) {
buffer.append(ch, start, length);
} else {
nextHandler.characters(ch, start, length);
}
}
The characters() method
© 2015 Adobe Systems Incorporated. All Rights Reserved. 22
public void endElement(String uri, String localName, String qName) {
if (collectingCharacters) {
String output = manipulate(buffer);
nextHandler.characters(output.toCharArray(), 0, output.length);
collectingCharacters = false;
buffer = null;
}
nextHandler.endElement(uri, localName, qName);
}
The characters() method
© 2015 Adobe Systems Incorporated. All Rights Reserved. 23
• Rewriting XML?
• Check out xml-generator and xml-serializer in ACS AEM Commons
• Rewriting JSON?
• Well…
Rewriting Other Things
© 2015 Adobe Systems Incorporated. All Rights Reserved. 24
public class JsonArrayGenerator implements Generator {
public void finished() throws IOException, SAXException {
try {
JSONArray array = new JSONArray(writer.toString());
contentHandler.startDocument();
for (int i = 0; i < array.length(); i++) {
final JSONObject obj = array.getJSONObject(i);
contentHandler.startElement(null, obj.toString(), null, null);
}
contentHandler.endDocument();
} catch (JSONException e) {
throw new SAXException("Unable to parse JSON Array", e);
}
}
}
JSON Array Generator
© 2015 Adobe Systems Incorporated. All Rights Reserved. 25
public abstract class JsonArrayContentHandler implements ContentHandler {
protected abstract void endArray();
protected abstract void startArray()
protected abstract void handleObject(JSONObject obj);
public void startDocument() { startArray(); }
public void startElement(String arg0, String arg1, String arg2, Attributes arg3)
throws SAXException {
try {
JSONObject obj = new JSONObject(arg1);
handleObject(obj);
} catch (JSONException e) {
throw new SAXException("Unable to parse JSON string", e);
}
}
public void endDocument() { endArray(); }
}
JSON Array Content Handler
© 2015 Adobe Systems Incorporated. All Rights Reserved. 26
protected void handleObject(JSONObject obj) {
obj.put("text", obj.get("name"));
contentHandler.startElement(null,
obj.toString(), null, null);
}
JSON Object Rewriting
© 2015 Adobe Systems Incorporated. All Rights Reserved. 27
• WebConsole Configuration Printer
• Recent Requests Web Console
Troubleshooting 211 LOG Found processor for post processing ProcessorConfiguration:
{
contentTypes=[text/html],order=-1, active=true, valid=true, processErrorResponse=true,
pipeline=(generator=Config(type=htmlparser, config=JcrPropertyMap
[node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/generator-htmlparser: {
jcr:primaryType = nt:unstructured, includeTags = [A, /A, IMG, AREA, FORM, BASE, LINK, SCRIPT,
BODY, /BODY, IFRAME, /IFRAME]}}], values={jcr:primaryType=nt:unstructured,
includeTags=[Ljava.lang.String;@3b9d3802}]), transformers=(Config(type=linkchecker, config={}),
Config(type=mobile, config=JcrPropertyMap
[node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/transformer-mobile: {
jcr:primaryType = nt:unstructured, component-optional = true}}],
values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=mobiledebug,
config=JcrPropertyMap
[node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/transformer-mobiledebug: {
jcr:primaryType = nt:unstructured, component-optional = true}}],
values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=contentsync,
config=JcrPropertyMap
[node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/transformer-contentsync: {
jcr:primaryType = nt:unstructured, component-optional = true}}],
values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=youtube-iframe,
config={}), serializer=Config(type=htmlwriter, config={}))
}
© 2015 Adobe Systems Incorporated. All Rights Reserved. 28
• Sling Rewriter is awesome
• It has very little to do with mod_rewrite
• Don’t use pipeline.mode=global
• Adjust includeTags if are you rewriting non-link HTML
elements.
• Be careful when implementing characters().
Final Thoughts
© 2015 Adobe Systems Incorporated. All Rights Reserved. 29

Weitere ähnliche Inhalte

Was ist angesagt?

Integration patterns in AEM 6
Integration patterns in AEM 6Integration patterns in AEM 6
Integration patterns in AEM 6Yuval Ararat
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template LanguageGabriel Walt
 
Sling Component Filters in CQ5
Sling Component Filters in CQ5 Sling Component Filters in CQ5
Sling Component Filters in CQ5 connectwebex
 
React Native - Workshop
React Native - WorkshopReact Native - Workshop
React Native - WorkshopFellipe Chagas
 
Seven Versions of One Web Application
Seven Versions of One Web ApplicationSeven Versions of One Web Application
Seven Versions of One Web ApplicationYakov Fain
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Matt Raible
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java DevelopersYakov Fain
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionBoldRadius Solutions
 
[2015/2016] Require JS and Handlebars JS
[2015/2016] Require JS and Handlebars JS[2015/2016] Require JS and Handlebars JS
[2015/2016] Require JS and Handlebars JSIvano Malavolta
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React NativeRami Sayar
 
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...JAX London
 
Building search app with ElasticSearch
Building search app with ElasticSearchBuilding search app with ElasticSearch
Building search app with ElasticSearchLukas Vlcek
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScriptYakov Fain
 
Java EE and Spring Side-by-Side
Java EE and Spring Side-by-SideJava EE and Spring Side-by-Side
Java EE and Spring Side-by-SideReza Rahman
 
GitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scalatakezoe
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshopStacy Goh
 
An Introduction to AngularJS
An Introduction to AngularJSAn Introduction to AngularJS
An Introduction to AngularJSFalk Hartmann
 
Android MvRx Framework 介紹
Android MvRx Framework 介紹Android MvRx Framework 介紹
Android MvRx Framework 介紹Kros Huang
 

Was ist angesagt? (20)

Integration patterns in AEM 6
Integration patterns in AEM 6Integration patterns in AEM 6
Integration patterns in AEM 6
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template Language
 
Sling Component Filters in CQ5
Sling Component Filters in CQ5 Sling Component Filters in CQ5
Sling Component Filters in CQ5
 
React Native - Workshop
React Native - WorkshopReact Native - Workshop
React Native - Workshop
 
Seven Versions of One Web Application
Seven Versions of One Web ApplicationSeven Versions of One Web Application
Seven Versions of One Web Application
 
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
Comparing Hot JavaScript Frameworks: AngularJS, Ember.js and React.js - Sprin...
 
Dart for Java Developers
Dart for Java DevelopersDart for Java Developers
Dart for Java Developers
 
How You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in ProductionHow You Convince Your Manager To Adopt Scala.js in Production
How You Convince Your Manager To Adopt Scala.js in Production
 
[2015/2016] Require JS and Handlebars JS
[2015/2016] Require JS and Handlebars JS[2015/2016] Require JS and Handlebars JS
[2015/2016] Require JS and Handlebars JS
 
Introduction to React Native
Introduction to React NativeIntroduction to React Native
Introduction to React Native
 
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
Spring Day | WaveMaker - Spring Roo - SpringSource Tool Suite: Choosing the R...
 
Building search app with ElasticSearch
Building search app with ElasticSearchBuilding search app with ElasticSearch
Building search app with ElasticSearch
 
React native
React nativeReact native
React native
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
Java EE and Spring Side-by-Side
Java EE and Spring Side-by-SideJava EE and Spring Side-by-Side
Java EE and Spring Side-by-Side
 
GitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by ScalaGitBucket: The perfect Github clone by Scala
GitBucket: The perfect Github clone by Scala
 
React && React Native workshop
React && React Native workshopReact && React Native workshop
React && React Native workshop
 
An Introduction to AngularJS
An Introduction to AngularJSAn Introduction to AngularJS
An Introduction to AngularJS
 
slingmodels
slingmodelsslingmodels
slingmodels
 
Android MvRx Framework 介紹
Android MvRx Framework 介紹Android MvRx Framework 介紹
Android MvRx Framework 介紹
 

Ähnlich wie Mastering the Sling Rewriter by Justin Edelson

Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to javaciklum_ods
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with KotlinRapidValue
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterHaehnchen
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegelermfrancis
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6Andy Butland
 
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D BosschaertLeveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaertmfrancis
 
Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM ICF CIRCUIT
 
Maintaining a dependency graph with weaver
Maintaining a dependency graph with weaverMaintaining a dependency graph with weaver
Maintaining a dependency graph with weaverScribd
 
OSGi Enterprise R6 specs are out! - David Bosschaert & Carsten Ziegeler
OSGi Enterprise R6 specs are out! - David Bosschaert & Carsten ZiegelerOSGi Enterprise R6 specs are out! - David Bosschaert & Carsten Ziegeler
OSGi Enterprise R6 specs are out! - David Bosschaert & Carsten Ziegelermfrancis
 
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018Wim Selles
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Sven Ruppert
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedToru Wonyoung Choi
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New FeaturesHaim Michael
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascriptmpnkhan
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Sven Ruppert
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupDavid Barreto
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'sAntônio Roberto Silva
 
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngineGoogle Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngineRoman Kirillov
 

Ähnlich wie Mastering the Sling Rewriter by Justin Edelson (20)

Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with Kotlin
 
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years laterSymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
SymfonyCon Berlin 2016 - Symfony Plugin for PhpStorm - 3 years later
 
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten ZiegelerNew and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
New and cool in OSGi R7 - David Bosschaert & Carsten Ziegeler
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6
 
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D BosschaertLeveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
Leveraging the Latest OSGi R7 Specifications - C Ziegeler & D Bosschaert
 
Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM Maximize the power of OSGi in AEM
Maximize the power of OSGi in AEM
 
Maintaining a dependency graph with weaver
Maintaining a dependency graph with weaverMaintaining a dependency graph with weaver
Maintaining a dependency graph with weaver
 
OSGi Enterprise R6 specs are out! - David Bosschaert & Carsten Ziegeler
OSGi Enterprise R6 specs are out! - David Bosschaert & Carsten ZiegelerOSGi Enterprise R6 specs are out! - David Bosschaert & Carsten Ziegeler
OSGi Enterprise R6 specs are out! - David Bosschaert & Carsten Ziegeler
 
Sst hackathon express
Sst hackathon expressSst hackathon express
Sst hackathon express
 
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018How React Native, Appium and me made each other shine @Frontmania 16-11-2018
How React Native, Appium and me made each other shine @Frontmania 16-11-2018
 
Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02Proxy Deep Dive JUG Saxony Day 2015-10-02
Proxy Deep Dive JUG Saxony Day 2015-10-02
 
Jetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO ExtendedJetpack, with new features in 2021 GDG Georgetown IO Extended
Jetpack, with new features in 2021 GDG Georgetown IO Extended
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascript
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
 
using Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API'susing Mithril.js + postgREST to build and consume API's
using Mithril.js + postgREST to build and consume API's
 
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngineGoogle Cloud Endpoints: Building Third-Party APIs on Google AppEngine
Google Cloud Endpoints: Building Third-Party APIs on Google AppEngine
 

Mehr von AEM HUB

Microservices for AEM by Maciej Majchrzak
Microservices for AEM by Maciej MajchrzakMicroservices for AEM by Maciej Majchrzak
Microservices for AEM by Maciej MajchrzakAEM HUB
 
When dispatcher caching is not enough by Jakub Wądołowski
When dispatcher caching is not enough by Jakub WądołowskiWhen dispatcher caching is not enough by Jakub Wądołowski
When dispatcher caching is not enough by Jakub WądołowskiAEM HUB
 
PhoneGap Enterprise Viewer by Anthony Rumsey
PhoneGap Enterprise Viewer by Anthony RumseyPhoneGap Enterprise Viewer by Anthony Rumsey
PhoneGap Enterprise Viewer by Anthony RumseyAEM HUB
 
Integrating Apache Wookie with AEM by Rima Mittal and Ankit Gubrani
Integrating Apache Wookie with AEM by Rima Mittal and Ankit GubraniIntegrating Apache Wookie with AEM by Rima Mittal and Ankit Gubrani
Integrating Apache Wookie with AEM by Rima Mittal and Ankit GubraniAEM HUB
 
Building Quality into the AEM Publication Workflow with Active Standards by D...
Building Quality into the AEM Publication Workflow with Active Standards by D...Building Quality into the AEM Publication Workflow with Active Standards by D...
Building Quality into the AEM Publication Workflow with Active Standards by D...AEM HUB
 
Touching the AEM component dialog by Mateusz Chromiński
Touching the AEM component dialog by Mateusz ChromińskiTouching the AEM component dialog by Mateusz Chromiński
Touching the AEM component dialog by Mateusz ChromińskiAEM HUB
 
How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...
How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...
How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...AEM HUB
 
How do you build flexible platforms that focuses on business needs? by Fahim...
How do you build flexible platforms that focuses on business needs?  by Fahim...How do you build flexible platforms that focuses on business needs?  by Fahim...
How do you build flexible platforms that focuses on business needs? by Fahim...AEM HUB
 
AEM Apps Enhanced: In-app Messaging and Beacons by John Fait
AEM Apps Enhanced: In-app Messaging and Beacons by John FaitAEM Apps Enhanced: In-app Messaging and Beacons by John Fait
AEM Apps Enhanced: In-app Messaging and Beacons by John FaitAEM HUB
 
Effectively Scale and Operate AEM with MongoDB by Norberto Leite
Effectively Scale and Operate AEM with MongoDB by Norberto LeiteEffectively Scale and Operate AEM with MongoDB by Norberto Leite
Effectively Scale and Operate AEM with MongoDB by Norberto LeiteAEM HUB
 
Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...
Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...
Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...AEM HUB
 
Adobe Marketing Cloud Integrations: Myth or Reality? by Holger Marsen
Adobe Marketing Cloud Integrations: Myth or Reality? by Holger MarsenAdobe Marketing Cloud Integrations: Myth or Reality? by Holger Marsen
Adobe Marketing Cloud Integrations: Myth or Reality? by Holger MarsenAEM HUB
 
Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt AEM HUB
 
Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon AEM HUB
 
REST in AEM by Roy Fielding
REST in AEM by Roy FieldingREST in AEM by Roy Fielding
REST in AEM by Roy FieldingAEM HUB
 
Adobe Summit 2015 - Penguin Random House - Accelerating Digital Transformation
Adobe Summit 2015 - Penguin Random House - Accelerating Digital TransformationAdobe Summit 2015 - Penguin Random House - Accelerating Digital Transformation
Adobe Summit 2015 - Penguin Random House - Accelerating Digital TransformationAEM HUB
 
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...AEM HUB
 
Sightly Beautiful Markup by Senol Tas
Sightly Beautiful Markup by Senol Tas Sightly Beautiful Markup by Senol Tas
Sightly Beautiful Markup by Senol Tas AEM HUB
 
Adobe Experience Manager - 6th Edition by Cedric Huesler
Adobe Experience Manager - 6th Edition by Cedric HueslerAdobe Experience Manager - 6th Edition by Cedric Huesler
Adobe Experience Manager - 6th Edition by Cedric HueslerAEM HUB
 
Organizing the world of CQ rest infinitive possibilities by Arkadiusz Kita
Organizing the world of CQ rest infinitive possibilities by Arkadiusz KitaOrganizing the world of CQ rest infinitive possibilities by Arkadiusz Kita
Organizing the world of CQ rest infinitive possibilities by Arkadiusz KitaAEM HUB
 

Mehr von AEM HUB (20)

Microservices for AEM by Maciej Majchrzak
Microservices for AEM by Maciej MajchrzakMicroservices for AEM by Maciej Majchrzak
Microservices for AEM by Maciej Majchrzak
 
When dispatcher caching is not enough by Jakub Wądołowski
When dispatcher caching is not enough by Jakub WądołowskiWhen dispatcher caching is not enough by Jakub Wądołowski
When dispatcher caching is not enough by Jakub Wądołowski
 
PhoneGap Enterprise Viewer by Anthony Rumsey
PhoneGap Enterprise Viewer by Anthony RumseyPhoneGap Enterprise Viewer by Anthony Rumsey
PhoneGap Enterprise Viewer by Anthony Rumsey
 
Integrating Apache Wookie with AEM by Rima Mittal and Ankit Gubrani
Integrating Apache Wookie with AEM by Rima Mittal and Ankit GubraniIntegrating Apache Wookie with AEM by Rima Mittal and Ankit Gubrani
Integrating Apache Wookie with AEM by Rima Mittal and Ankit Gubrani
 
Building Quality into the AEM Publication Workflow with Active Standards by D...
Building Quality into the AEM Publication Workflow with Active Standards by D...Building Quality into the AEM Publication Workflow with Active Standards by D...
Building Quality into the AEM Publication Workflow with Active Standards by D...
 
Touching the AEM component dialog by Mateusz Chromiński
Touching the AEM component dialog by Mateusz ChromińskiTouching the AEM component dialog by Mateusz Chromiński
Touching the AEM component dialog by Mateusz Chromiński
 
How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...
How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...
How to build a Social Intranet with Adobe Sites and 3rd Party products ... us...
 
How do you build flexible platforms that focuses on business needs? by Fahim...
How do you build flexible platforms that focuses on business needs?  by Fahim...How do you build flexible platforms that focuses on business needs?  by Fahim...
How do you build flexible platforms that focuses on business needs? by Fahim...
 
AEM Apps Enhanced: In-app Messaging and Beacons by John Fait
AEM Apps Enhanced: In-app Messaging and Beacons by John FaitAEM Apps Enhanced: In-app Messaging and Beacons by John Fait
AEM Apps Enhanced: In-app Messaging and Beacons by John Fait
 
Effectively Scale and Operate AEM with MongoDB by Norberto Leite
Effectively Scale and Operate AEM with MongoDB by Norberto LeiteEffectively Scale and Operate AEM with MongoDB by Norberto Leite
Effectively Scale and Operate AEM with MongoDB by Norberto Leite
 
Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...
Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...
Adobe Managed Services: Complicated Cloud Deployments by Adam Pazik, Mike Til...
 
Adobe Marketing Cloud Integrations: Myth or Reality? by Holger Marsen
Adobe Marketing Cloud Integrations: Myth or Reality? by Holger MarsenAdobe Marketing Cloud Integrations: Myth or Reality? by Holger Marsen
Adobe Marketing Cloud Integrations: Myth or Reality? by Holger Marsen
 
Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt Responsive Websites and Grid-Based Layouts by Gabriel Walt
Responsive Websites and Grid-Based Layouts by Gabriel Walt
 
Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon Creativity without comprise by Cleve Gibbon
Creativity without comprise by Cleve Gibbon
 
REST in AEM by Roy Fielding
REST in AEM by Roy FieldingREST in AEM by Roy Fielding
REST in AEM by Roy Fielding
 
Adobe Summit 2015 - Penguin Random House - Accelerating Digital Transformation
Adobe Summit 2015 - Penguin Random House - Accelerating Digital TransformationAdobe Summit 2015 - Penguin Random House - Accelerating Digital Transformation
Adobe Summit 2015 - Penguin Random House - Accelerating Digital Transformation
 
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
Socialize your Exceptional Web Experience – Adobe AEM & IBM Connections by He...
 
Sightly Beautiful Markup by Senol Tas
Sightly Beautiful Markup by Senol Tas Sightly Beautiful Markup by Senol Tas
Sightly Beautiful Markup by Senol Tas
 
Adobe Experience Manager - 6th Edition by Cedric Huesler
Adobe Experience Manager - 6th Edition by Cedric HueslerAdobe Experience Manager - 6th Edition by Cedric Huesler
Adobe Experience Manager - 6th Edition by Cedric Huesler
 
Organizing the world of CQ rest infinitive possibilities by Arkadiusz Kita
Organizing the world of CQ rest infinitive possibilities by Arkadiusz KitaOrganizing the world of CQ rest infinitive possibilities by Arkadiusz Kita
Organizing the world of CQ rest infinitive possibilities by Arkadiusz Kita
 

Kürzlich hochgeladen

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobeapidays
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024SynarionITSolutions
 
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
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businesspanagenda
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
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
 
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
 
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
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)wesley chun
 
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
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProduct Anonymous
 
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
 
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
 
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
 
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
 
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
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MIND CTI
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAndrey Devyatkin
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 

Kürzlich hochgeladen (20)

Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, AdobeApidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
Apidays New York 2024 - Scaling API-first by Ian Reasor and Radu Cotescu, Adobe
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024Top 10 Most Downloaded Games on Play Store in 2024
Top 10 Most Downloaded Games on Play Store in 2024
 
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
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
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
 
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
 
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
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
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
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
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, ...
 
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
 
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
 
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
 
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
 
MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024MINDCTI Revenue Release Quarter One 2024
MINDCTI Revenue Release Quarter One 2024
 
AWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of TerraformAWS Community Day CPH - Three problems of Terraform
AWS Community Day CPH - Three problems of Terraform
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 

Mastering the Sling Rewriter by Justin Edelson

  • 1. Mastering the Sling Rewriter Justin Edelson AEM Evangelist
  • 2. © 2015 Adobe Systems Incorporated. All Rights Reserved. 2
  • 3. © 2015 Adobe Systems Incorporated. All Rights Reserved. 3 • Sling Rewriter an Apache Sling module included in AEM. • Performs transformations of rendered content (typically HTML) • Doesn’t know anything about your components • Pipeline-orientated • Based on Simple API for XML (SAX) What is the Sling Rewriter?
  • 4. © 2015 Adobe Systems Incorporated. All Rights Reserved. 4 No. Sling Rewriter is about rewriting the (HTML) output. mod_rewrite is about rewriting the requesting URL. There is an Apache module, mod_ext_filter, which can be used for output rewriting. Is Sling Rewriter related to mod_rewrite?
  • 5. © 2015 Adobe Systems Incorporated. All Rights Reserved. 5 Transformer Rewriter Pipeline Output Content (HTML, XML) Output Content (HTML, XML) Generator SAX Events SAX Events Transformer SerializerTransformer Pipeline
  • 6. © 2015 Adobe Systems Incorporated. All Rights Reserved. 6 Stored in the repository. Always /apps/SOMETHING/config/rewriter Defines when the pipeline is executed Defines how the pipeline is composed Rewriter Pipeline Configurations
  • 7. © 2015 Adobe Systems Incorporated. All Rights Reserved. 7 contentTypes – Response Content Type (e.g. text/html) extensions – Request Extension (e.g. html) resourceTypes – Resolved Resource Type selectors – Request selectors (soon; not in AEM 6.1) paths – Path prefixes enabled – true/false order – highest wins Enablement Options All are optional
  • 8. © 2015 Adobe Systems Incorporated. All Rights Reserved. 8 generatorType transformerTypes serializerType Pipeline Options @Component @Service @Property(name = "pipeline.type”, value = "xml-generator") public class XMLParserGeneratorFactory implements GeneratorFactory { } @Component @Service @Property(name = "pipeline.type", value = "versioned-clientlibs") public class VersionedClientlibsTransformerFactory implements TransformerFactory { } @Component @Service @Property(name = "pipeline.type”, value = "xml-serializer") public class PlainXMLSerializerFactory implements SerializerFactory { }
  • 9. © 2015 Adobe Systems Incorporated. All Rights Reserved. 9 Nodes named <component-type>-<component-name> Only one defined property - component-optional Everything else is up to the particular component to define Pipeline Element Configuration
  • 10. © 2015 Adobe Systems Incorporated. All Rights Reserved. 10 Implement two interfaces @Component @Service @Property(name = "pipeline.type”, value = ”mytrans") public class MyTransformerFactory implements TransformerFactory { public Transformer createTransformer() { return new MyTransformer(); } private class MyTransformer implements Transformer { … } } Creating your own Transformer
  • 11. © 2015 Adobe Systems Incorporated. All Rights Reserved. 11 Transformers can be declared as global. @Component @Service @Property(name="pipeline.mode", value="global") public class MyEvilTransformer implements TransformerFactory {} This is a bad idea. Don’t do it. “global” Transformers
  • 12. © 2015 Adobe Systems Incorporated. All Rights Reserved. 12 public void startElement(String namespaceURI, String localName, String qName, Attributes atts) { nextHandler.startElement(namespaceURI, localName, qName, rebuildAttributes(localName, atts)); } private Attributes rebuildAttributes(String elementName, Attributes attrs) { if (“a”.equals(elementName)) { AttributesImpl newAttrs = new AttributesImpl(attrs); … return newAttrs; } else { return attrs; } } Creating your own Transformer
  • 13. © 2015 Adobe Systems Incorporated. All Rights Reserved. 13 <iframe width="420" height="315" src=“https://www.youtube.com/embed/QfvFWSQQ_0M” frameborder="0" allowfullscreen> </iframe> <div class="youtube-container"> <iframe width="420" height="315" src=“https://www.youtube.com/embed/QfvFWSQQ_0M” frameborder="0" allowfullscreen class=“youtube-wrapped”> </iframe> </div> Transformer Use Case Wrapping YouTube Embedded IFrames
  • 14. © 2015 Adobe Systems Incorporated. All Rights Reserved. 14 public void startElement(String uri, String localName, String qName, Attributes atts) { if ("iframe".equals(localName) && needsWrapping(atts)) { startWrapper(); needToUnwrap = true; AttributesImpl newAtts = new AttributesImpl(); newAtts.setAttributes(atts); newAtts.addAttribute("", "class", "class", "CDATA", "youtube-wrapped"); nextHandler.startElement(uri, localName, qName, newAtts); } else { nextHandler.startElement(uri, localName, qName, atts); } } public void endElement(String uri, String localName, String qName) { nextHandler.endElement(uri, localName, qName); if (needToUnwrap && localName.equals("iframe")) { endWrapper(); needToUnwrap = false; } } Adding YouTube Wrapper
  • 15. © 2015 Adobe Systems Incorporated. All Rights Reserved. 15 boolean needsWrapping(Attributes atts) { final String src = atts.getValue("src"); if (src == null) { return false; } if (src.contains("youtube")) { final String classAttr = atts.getValue("class"); if (classAttr == null) { return true; } else if (classAttr.indexOf("youtube-wrapped") > -1) { return false; } else { return true; } } return false; } Adding YouTube Wrapper
  • 16. © 2015 Adobe Systems Incorporated. All Rights Reserved. 16 void endWrapper(){ nextHandler.endElement("", "div", "div"); } void startWrapper(){ AttributesImpl newAtts = new AttributesImpl(); newAtts.addAttribute("", "class", "class", "CDATA”, "youtube-container"); nextHandler.startElement("", "div", "div", newAtts); } Adding YouTube Wrapper
  • 17. © 2015 Adobe Systems Incorporated. All Rights Reserved. 17 • AEM’s HTML parser ignores <iframe> by default. • Need to adjust the configuration • With a node named generator-htmlparser BUT…
  • 18. © 2015 Adobe Systems Incorporated. All Rights Reserved. 18 The init() method
  • 19. © 2015 Adobe Systems Incorporated. All Rights Reserved. 19 The characters() method is hard… <div>foo</div> characters(['f','o','o'], 0, 2); characters(['f'], 0, 1); characters(['o'], 0, 1); characters(['o'], 0, 1); characters(['>','f'], 1, 2); characters(['o', 'o'], 0, 2); The characters() method “SAX parsers may return all contiguous character data in a single chunk, or they may split it into several chunks.“
  • 20. © 2015 Adobe Systems Incorporated. All Rights Reserved. 20 For simple manipulations: public void characters(char ch[],int start, int length) { String str = new String(ch, start, length); str = str.toUpperCase(); nextHandler.characters(str.toCharArray(), 0, length); } The characters() method
  • 21. © 2015 Adobe Systems Incorporated. All Rights Reserved. 21 For complex manipulations: public void startElement(String uri, String localName, String qName, Attributes atts) { if (isSpecialElement(localName, atts) { collectingCharacters = true; buffer = new StringBuilder(); } nextHandler.startElement(uri, localName, qName, atts); } public void characters(char[] ch, int start, int length) { if (collectingCharacters) { buffer.append(ch, start, length); } else { nextHandler.characters(ch, start, length); } } The characters() method
  • 22. © 2015 Adobe Systems Incorporated. All Rights Reserved. 22 public void endElement(String uri, String localName, String qName) { if (collectingCharacters) { String output = manipulate(buffer); nextHandler.characters(output.toCharArray(), 0, output.length); collectingCharacters = false; buffer = null; } nextHandler.endElement(uri, localName, qName); } The characters() method
  • 23. © 2015 Adobe Systems Incorporated. All Rights Reserved. 23 • Rewriting XML? • Check out xml-generator and xml-serializer in ACS AEM Commons • Rewriting JSON? • Well… Rewriting Other Things
  • 24. © 2015 Adobe Systems Incorporated. All Rights Reserved. 24 public class JsonArrayGenerator implements Generator { public void finished() throws IOException, SAXException { try { JSONArray array = new JSONArray(writer.toString()); contentHandler.startDocument(); for (int i = 0; i < array.length(); i++) { final JSONObject obj = array.getJSONObject(i); contentHandler.startElement(null, obj.toString(), null, null); } contentHandler.endDocument(); } catch (JSONException e) { throw new SAXException("Unable to parse JSON Array", e); } } } JSON Array Generator
  • 25. © 2015 Adobe Systems Incorporated. All Rights Reserved. 25 public abstract class JsonArrayContentHandler implements ContentHandler { protected abstract void endArray(); protected abstract void startArray() protected abstract void handleObject(JSONObject obj); public void startDocument() { startArray(); } public void startElement(String arg0, String arg1, String arg2, Attributes arg3) throws SAXException { try { JSONObject obj = new JSONObject(arg1); handleObject(obj); } catch (JSONException e) { throw new SAXException("Unable to parse JSON string", e); } } public void endDocument() { endArray(); } } JSON Array Content Handler
  • 26. © 2015 Adobe Systems Incorporated. All Rights Reserved. 26 protected void handleObject(JSONObject obj) { obj.put("text", obj.get("name")); contentHandler.startElement(null, obj.toString(), null, null); } JSON Object Rewriting
  • 27. © 2015 Adobe Systems Incorporated. All Rights Reserved. 27 • WebConsole Configuration Printer • Recent Requests Web Console Troubleshooting 211 LOG Found processor for post processing ProcessorConfiguration: { contentTypes=[text/html],order=-1, active=true, valid=true, processErrorResponse=true, pipeline=(generator=Config(type=htmlparser, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/generator-htmlparser: { jcr:primaryType = nt:unstructured, includeTags = [A, /A, IMG, AREA, FORM, BASE, LINK, SCRIPT, BODY, /BODY, IFRAME, /IFRAME]}}], values={jcr:primaryType=nt:unstructured, includeTags=[Ljava.lang.String;@3b9d3802}]), transformers=(Config(type=linkchecker, config={}), Config(type=mobile, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/transformer-mobile: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=mobiledebug, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/transformer-mobiledebug: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=contentsync, config=JcrPropertyMap [node=Node[NodeDelegate{tree=/libs/cq/config/rewriter/default/transformer-contentsync: { jcr:primaryType = nt:unstructured, component-optional = true}}], values={jcr:primaryType=nt:unstructured, component-optional=true}]), Config(type=youtube-iframe, config={}), serializer=Config(type=htmlwriter, config={})) }
  • 28. © 2015 Adobe Systems Incorporated. All Rights Reserved. 28 • Sling Rewriter is awesome • It has very little to do with mod_rewrite • Don’t use pipeline.mode=global • Adjust includeTags if are you rewriting non-link HTML elements. • Be careful when implementing characters(). Final Thoughts
  • 29. © 2015 Adobe Systems Incorporated. All Rights Reserved. 29

Hinweis der Redaktion

  1. It is actually possible to name these nodes component-type dash index. It would be better to avoid this as it is a little error prone, but in the edge case where you use the same transformer multiple times but with different configurations, you’d need to use this.
  2. The reason this is a bad idea is that these transformers are hard to control – they always execute and they always execute before or after any transfomers defined in the pipeline configuration, based on a positive or negative service ranking.