SlideShare una empresa de Scribd logo
1 de 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

Más contenido relacionado

La actualidad más candente

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 knowPrabhdeep Singh
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template LanguageGabriel Walt
 
Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson AEM HUB
 
Aem dispatcher – tips & tricks
Aem dispatcher – tips & tricksAem dispatcher – tips & tricks
Aem dispatcher – tips & tricksAshokkumar T A
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep DiveGabriel Walt
 
AEM and Sling
AEM and SlingAEM and Sling
AEM and SlingLo Ki
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency InjectionAnuj Singh Rajput
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교JungWoon Lee
 
서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018
서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018 서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018
서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018 Amazon Web Services Korea
 
Dynamic Components using Single-Page-Application Concepts in AEM/CQ
Dynamic Components using Single-Page-Application Concepts in AEM/CQDynamic Components using Single-Page-Application Concepts in AEM/CQ
Dynamic Components using Single-Page-Application Concepts in AEM/CQNetcetera
 
Infrastructure Continuous Delivery Using AWS CloudFormation
Infrastructure Continuous Delivery Using AWS CloudFormationInfrastructure Continuous Delivery Using AWS CloudFormation
Infrastructure Continuous Delivery Using AWS CloudFormationAmazon Web Services
 
Basics of Solr and Solr Integration with AEM6
Basics of Solr and Solr Integration with AEM6Basics of Solr and Solr Integration with AEM6
Basics of Solr and Solr Integration with AEM6DEEPAK KHETAWAT
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018Amazon Web Services Korea
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Hitesh-Java
 
Experience and Content Fragment
Experience and Content FragmentExperience and Content Fragment
Experience and Content FragmentHeena Madan
 
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중Amazon Web Services Korea
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot ApplicationsVMware Tanzu
 

La actualidad más candente (20)

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
 
AEM Sightly Template Language
AEM Sightly Template LanguageAEM Sightly Template Language
AEM Sightly Template Language
 
Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson
 
Aem dispatcher – tips & tricks
Aem dispatcher – tips & tricksAem dispatcher – tips & tricks
Aem dispatcher – tips & tricks
 
AEM Sightly Deep Dive
AEM Sightly Deep DiveAEM Sightly Deep Dive
AEM Sightly Deep Dive
 
AEM and Sling
AEM and SlingAEM and Sling
AEM and Sling
 
Sling Models Overview
Sling Models OverviewSling Models Overview
Sling Models Overview
 
Spring framework IOC and Dependency Injection
Spring framework  IOC and Dependency InjectionSpring framework  IOC and Dependency Injection
Spring framework IOC and Dependency Injection
 
IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교IBM JVM 소개 - Oracle JVM 과 비교
IBM JVM 소개 - Oracle JVM 과 비교
 
서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018
서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018 서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018
서버리스 웹 애플리케이션 구축 방법론::김현수:: AWS Summit Seoul 2018
 
Dynamic Components using Single-Page-Application Concepts in AEM/CQ
Dynamic Components using Single-Page-Application Concepts in AEM/CQDynamic Components using Single-Page-Application Concepts in AEM/CQ
Dynamic Components using Single-Page-Application Concepts in AEM/CQ
 
Infrastructure Continuous Delivery Using AWS CloudFormation
Infrastructure Continuous Delivery Using AWS CloudFormationInfrastructure Continuous Delivery Using AWS CloudFormation
Infrastructure Continuous Delivery Using AWS CloudFormation
 
Basics of Solr and Solr Integration with AEM6
Basics of Solr and Solr Integration with AEM6Basics of Solr and Solr Integration with AEM6
Basics of Solr and Solr Integration with AEM6
 
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018 Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
Terraform을 이용한 Infrastructure as Code 실전 구성하기 :: 변정훈::AWS Summit Seoul 2018
 
Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans Spring - Part 1 - IoC, Di and Beans
Spring - Part 1 - IoC, Di and Beans
 
Experience and Content Fragment
Experience and Content FragmentExperience and Content Fragment
Experience and Content Fragment
 
Introduction to Spring Boot
Introduction to Spring BootIntroduction to Spring Boot
Introduction to Spring Boot
 
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
판교 개발자 데이 – Aws가 제안하는 서버리스 아키텍처 – 김필중
 
AWS EC2
AWS EC2AWS EC2
AWS EC2
 
Testing Spring Boot Applications
Testing Spring Boot ApplicationsTesting Spring Boot Applications
Testing Spring Boot Applications
 

Destacado

Demystifying Oak Search
Demystifying Oak SearchDemystifying Oak Search
Demystifying Oak SearchJustin Edelson
 
Thoughts on Component Resuse
Thoughts on Component ResuseThoughts on Component Resuse
Thoughts on Component ResuseJustin 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 ManagerJustin Edelson
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonAEM HUB
 
Extra AEM Development Tools
Extra AEM Development ToolsExtra AEM Development Tools
Extra AEM Development ToolsJustin Edelson
 
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 ThingsJustin Edelson
 

Destacado (6)

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
 
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
 
Mastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin EdelsonMastering the Sling Rewriter by Justin Edelson
Mastering the Sling Rewriter by Justin Edelson
 
Extra AEM Development Tools
Extra AEM Development ToolsExtra AEM Development Tools
Extra AEM Development Tools
 
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
 

Similar a Mastering the Sling Rewriter in AEM

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
 

Similar a Mastering the Sling Rewriter in AEM (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
 

Último

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024The Digital Insurer
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slidespraypatel2
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityPrincipled Technologies
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonetsnaman860154
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxKatpro Technologies
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
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
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerThousandEyes
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEarley Information Science
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...gurkirankumar98700
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdfhans926745
 

Último (20)

Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024Partners Life - Insurer Innovation Award 2024
Partners Life - Insurer Innovation Award 2024
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
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
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
Slack Application Development 101 Slides
Slack Application Development 101 SlidesSlack Application Development 101 Slides
Slack Application Development 101 Slides
 
A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
How to convert PDF to text with Nanonets
How to convert PDF to text with NanonetsHow to convert PDF to text with Nanonets
How to convert PDF to text with Nanonets
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptxFactors to Consider When Choosing Accounts Payable Services Providers.pptx
Factors to Consider When Choosing Accounts Payable Services Providers.pptx
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
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
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptxEIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
EIS-Webinar-Prompt-Knowledge-Eng-2024-04-08.pptx
 
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
Kalyanpur ) Call Girls in Lucknow Finest Escorts Service 🍸 8923113531 🎰 Avail...
 
[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf[2024]Digital Global Overview Report 2024 Meltwater.pdf
[2024]Digital Global Overview Report 2024 Meltwater.pdf
 

Mastering the Sling Rewriter in AEM

  • 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

Notas del editor

  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.