SlideShare a Scribd company logo
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

More Related Content

What's hot

AEM - Client Libraries
AEM - Client LibrariesAEM - Client Libraries
AEM - Client Libraries
Prabhdeep Singh
 
Introduction to Sightly and Sling Models
Introduction to Sightly and Sling ModelsIntroduction to Sightly and Sling Models
Introduction to Sightly and Sling Models
Stefano Celentano
 
Cookies and sessions
Cookies and sessionsCookies and sessions
Cookies and sessions
Lena Petsenchuk
 
HTL(Sightly) - All you need to know
HTL(Sightly) - All you need to knowHTL(Sightly) - All you need to know
HTL(Sightly) - All you need to know
Prabhdeep Singh
 
JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)
WebStackAcademy
 
Express js
Express jsExpress js
Express js
Manav Prasad
 
Apache Server Tutorial
Apache Server TutorialApache Server Tutorial
Apache Server Tutorial
Jagat Kothari
 
Prometheus Overview
Prometheus OverviewPrometheus Overview
Prometheus Overview
Brian Brazil
 
Heap Dump Analysis - AEM: Real World Issues
Heap Dump Analysis - AEM: Real World IssuesHeap Dump Analysis - AEM: Real World Issues
Heap Dump Analysis - AEM: Real World Issues
Kanika Gera
 
AEM Rich Text Editor (RTE) Deep Dive
AEM Rich Text Editor (RTE) Deep DiveAEM Rich Text Editor (RTE) Deep Dive
AEM Rich Text Editor (RTE) Deep Dive
Hanish Bansal
 
Intro to beautiful soup
Intro to beautiful soupIntro to beautiful soup
Intro to beautiful soup
Andreas Chandra
 
the-pfsense-documentation.pdf
the-pfsense-documentation.pdfthe-pfsense-documentation.pdf
the-pfsense-documentation.pdf
FrankCosta30
 
Apache web server
Apache web serverApache web server
Apache web server
Rishabh Bahukhandi
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & Streams
Eyal Vardi
 
Ask the expert AEM Assets best practices 092016
Ask the expert  AEM Assets best practices 092016Ask the expert  AEM Assets best practices 092016
Ask the expert AEM Assets best practices 092016
AdobeMarketingCloud
 
Introduction to Maven
Introduction to MavenIntroduction to Maven
Introduction to Maven
Mindfire Solutions
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the Things
Justin Edelson
 
Introduction to Rust
Introduction to RustIntroduction to Rust
Introduction to Rust
Jean Carlo Machado
 
게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트
게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트
게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트
Amazon Web Services Korea
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
Simon Willison
 

What's hot (20)

AEM - Client Libraries
AEM - Client LibrariesAEM - Client Libraries
AEM - Client Libraries
 
Introduction to Sightly and Sling Models
Introduction to Sightly and Sling ModelsIntroduction to Sightly and Sling Models
Introduction to Sightly and Sling Models
 
Cookies and sessions
Cookies and sessionsCookies and sessions
Cookies and sessions
 
HTL(Sightly) - All you need to know
HTL(Sightly) - All you need to knowHTL(Sightly) - All you need to know
HTL(Sightly) - All you need to know
 
JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)JavaScript - Chapter 13 - Browser Object Model(BOM)
JavaScript - Chapter 13 - Browser Object Model(BOM)
 
Express js
Express jsExpress js
Express js
 
Apache Server Tutorial
Apache Server TutorialApache Server Tutorial
Apache Server Tutorial
 
Prometheus Overview
Prometheus OverviewPrometheus Overview
Prometheus Overview
 
Heap Dump Analysis - AEM: Real World Issues
Heap Dump Analysis - AEM: Real World IssuesHeap Dump Analysis - AEM: Real World Issues
Heap Dump Analysis - AEM: Real World Issues
 
AEM Rich Text Editor (RTE) Deep Dive
AEM Rich Text Editor (RTE) Deep DiveAEM Rich Text Editor (RTE) Deep Dive
AEM Rich Text Editor (RTE) Deep Dive
 
Intro to beautiful soup
Intro to beautiful soupIntro to beautiful soup
Intro to beautiful soup
 
the-pfsense-documentation.pdf
the-pfsense-documentation.pdfthe-pfsense-documentation.pdf
the-pfsense-documentation.pdf
 
Apache web server
Apache web serverApache web server
Apache web server
 
Node.js File system & Streams
Node.js File system & StreamsNode.js File system & Streams
Node.js File system & Streams
 
Ask the expert AEM Assets best practices 092016
Ask the expert  AEM Assets best practices 092016Ask the expert  AEM Assets best practices 092016
Ask the expert AEM Assets best practices 092016
 
Introduction to Maven
Introduction to MavenIntroduction to Maven
Introduction to Maven
 
Omnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the ThingsOmnisearch in AEM 6.2 - Search All the Things
Omnisearch in AEM 6.2 - Search All the Things
 
Introduction to Rust
Introduction to RustIntroduction to Rust
Introduction to Rust
 
게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트
게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트
게임사를 위한 Amazon GameLift 세션 - 이정훈, AWS 솔루션즈 아키텍트
 
Learning jQuery in 30 minutes
Learning jQuery in 30 minutesLearning jQuery in 30 minutes
Learning jQuery in 30 minutes
 

Similar to Mastering the Sling Rewriter

Bring the fun back to java
Bring the fun back to javaBring the fun back to java
Bring the fun back to java
ciklum_ods
 
Appium Automation with Kotlin
Appium Automation with KotlinAppium Automation with Kotlin
Appium Automation with Kotlin
RapidValue
 
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
Haehnchen
 
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
mfrancis
 
ASP.Net 5 and C# 6
ASP.Net 5 and C# 6ASP.Net 5 and C# 6
ASP.Net 5 and C# 6
Andy 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 Bosschaert
mfrancis
 
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 weaver
Scribd
 
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
mfrancis
 
Sst hackathon express
Sst hackathon expressSst hackathon express
Sst hackathon express
Aeshan Wijetunge
 
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
Wim 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-02
Sven 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 Extended
Toru Wonyoung Choi
 
Java11 New Features
Java11 New FeaturesJava11 New Features
Java11 New Features
Haim Michael
 
Effecient javascript
Effecient javascriptEffecient javascript
Effecient javascript
mpnkhan
 
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
Sven Ruppert
 
Arquitecturas de microservicios - Medianet Software
Arquitecturas de microservicios   -  Medianet SoftwareArquitecturas de microservicios   -  Medianet Software
Arquitecturas de microservicios - Medianet Software
Ernesto Hernández Rodríguez
 
Angular Optimization Web Performance Meetup
Angular Optimization Web Performance MeetupAngular Optimization Web Performance Meetup
Angular Optimization Web Performance Meetup
David 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's
Antô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 AppEngine
Roman Kirillov
 

Similar to Mastering the Sling Rewriter (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
 

More from Justin Edelson

PhoneGap Enterprise Viewer - ConnectCon 2015
PhoneGap Enterprise Viewer - ConnectCon 2015PhoneGap Enterprise Viewer - ConnectCon 2015
PhoneGap Enterprise Viewer - ConnectCon 2015
Justin Edelson
 
Building Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience ManagerBuilding Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience Manager
Justin Edelson
 
Extra AEM Development Tools
Extra AEM Development ToolsExtra AEM Development Tools
Extra AEM Development Tools
Justin Edelson
 
Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak Search
Justin Edelson
 
Thoughts on Component Resuse
Thoughts on Component ResuseThoughts on Component Resuse
Thoughts on Component Resuse
Justin Edelson
 
Sling Models Overview
Sling Models OverviewSling Models Overview
Sling Models Overview
Justin Edelson
 

More from Justin Edelson (6)

PhoneGap Enterprise Viewer - ConnectCon 2015
PhoneGap Enterprise Viewer - ConnectCon 2015PhoneGap Enterprise Viewer - ConnectCon 2015
PhoneGap Enterprise Viewer - ConnectCon 2015
 
Building Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience ManagerBuilding Creative Product Extensions with Experience Manager
Building Creative Product Extensions with Experience Manager
 
Extra AEM Development Tools
Extra AEM Development ToolsExtra AEM Development Tools
Extra AEM Development Tools
 
Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak Search
 
Thoughts on Component Resuse
Thoughts on Component ResuseThoughts on Component Resuse
Thoughts on Component Resuse
 
Sling Models Overview
Sling Models OverviewSling Models Overview
Sling Models Overview
 

Recently uploaded

Figma AI Design Generator_ In-Depth Review.pdf
Figma AI Design Generator_ In-Depth Review.pdfFigma AI Design Generator_ In-Depth Review.pdf
Figma AI Design Generator_ In-Depth Review.pdf
Management Institute of Skills Development
 
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
Priyanka Aash
 
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
Edge AI and Vision Alliance
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
Adam Dunkels
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
Shiv Technolabs
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
aakash malhotra
 
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
alexjohnson7307
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
Brian Pichman
 
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptxRPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
SynapseIndia
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
Zilliz
 
Introduction-to-the-IAM-Platform-Implementation-Plan.pptx
Introduction-to-the-IAM-Platform-Implementation-Plan.pptxIntroduction-to-the-IAM-Platform-Implementation-Plan.pptx
Introduction-to-the-IAM-Platform-Implementation-Plan.pptx
313mohammedarshad
 
July Patch Tuesday
July Patch TuesdayJuly Patch Tuesday
July Patch Tuesday
Ivanti
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
maigasapphire
 
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Nicolás Lopéz
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
Matthias Neugebauer
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
BrainSell Technologies
 
TrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-In
TrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-InTrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-In
TrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-In
TrustArc
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
Safe Software
 
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and OllamaTirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Zilliz
 
IPLOOK Remote-Sensing Satellite Solution
IPLOOK Remote-Sensing Satellite SolutionIPLOOK Remote-Sensing Satellite Solution
IPLOOK Remote-Sensing Satellite Solution
IPLOOK Networks
 

Recently uploaded (20)

Figma AI Design Generator_ In-Depth Review.pdf
Figma AI Design Generator_ In-Depth Review.pdfFigma AI Design Generator_ In-Depth Review.pdf
Figma AI Design Generator_ In-Depth Review.pdf
 
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
(CISOPlatform Summit & SACON 2024) Digital Personal Data Protection Act.pdf
 
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
“Deploying Large Language Models on a Raspberry Pi,” a Presentation from Usef...
 
How to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptxHow to Build a Profitable IoT Product.pptx
How to Build a Profitable IoT Product.pptx
 
The Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF GuideThe Role of IoT in Australian Mobile App Development - PDF Guide
The Role of IoT in Australian Mobile App Development - PDF Guide
 
Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024Three New Criminal Laws in India 1 July 2024
Three New Criminal Laws in India 1 July 2024
 
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
leewayhertz.com-AI agents for healthcare Applications benefits and implementa...
 
Uncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in LibrariesUncharted Together- Navigating AI's New Frontiers in Libraries
Uncharted Together- Navigating AI's New Frontiers in Libraries
 
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptxRPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
RPA In Healthcare Benefits, Use Case, Trend And Challenges 2024.pptx
 
Using LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and MilvusUsing LLM Agents with Llama 3, LangGraph and Milvus
Using LLM Agents with Llama 3, LangGraph and Milvus
 
Introduction-to-the-IAM-Platform-Implementation-Plan.pptx
Introduction-to-the-IAM-Platform-Implementation-Plan.pptxIntroduction-to-the-IAM-Platform-Implementation-Plan.pptx
Introduction-to-the-IAM-Platform-Implementation-Plan.pptx
 
July Patch Tuesday
July Patch TuesdayJuly Patch Tuesday
July Patch Tuesday
 
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
Girls Call Churchgate 9910780858 Provide Best And Top Girl Service And No1 in...
 
Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024Vertex AI Agent Builder - GDG Alicante - Julio 2024
Vertex AI Agent Builder - GDG Alicante - Julio 2024
 
Opencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of MünsterOpencast Summit 2024 — Opencast @ University of Münster
Opencast Summit 2024 — Opencast @ University of Münster
 
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdfAcumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
Acumatica vs. Sage Intacct vs. NetSuite _ NOW CFO.pdf
 
TrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-In
TrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-InTrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-In
TrustArc Webinar - 2024 Data Privacy Trends: A Mid-Year Check-In
 
Data Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining DataData Integration Basics: Merging & Joining Data
Data Integration Basics: Merging & Joining Data
 
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and OllamaTirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
Tirana Tech Meetup - Agentic RAG with Milvus, Llama3 and Ollama
 
IPLOOK Remote-Sensing Satellite Solution
IPLOOK Remote-Sensing Satellite SolutionIPLOOK Remote-Sensing Satellite Solution
IPLOOK Remote-Sensing Satellite Solution
 

Mastering the Sling Rewriter

  • 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

Editor's Notes

  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.