SlideShare a Scribd company logo
1 of 65
Download to read offline
AEM6+ Component Development 
Adobe Experience Manager 
@GabrielWalt, Product Manager
Specification and TCK open sourced to GitHub. 
Reference implementation donated to Apache Sling. 
Follow @sightlyio on Twitter. 
http://docs.adobe.com/docs/en/aem/6-0/develop/sightly.html 
Adobe Experience Manager
Adobe Experience Manager 
§ 1 Why Sightly 
§ 2 Features 
§ 3 Tooling
Project Efficiency 
Adobe.com estimated that it reduced their project 
costs by about 25% 
JSP Project 
Adobe Experience Manager 
Design 
HTML/CSS 
Template 
JSP 
Logic 
Java 
Design 
HTML/CSS 
Template 
Sightly HTML 
Logic 
Use-API 
Project 
Management Sightly 
Management 
~25% 
Effort / Cost
Development Workflow 
Improves project efficiency by removing the pain of 
JSP and Java development 
Adobe Experience Manager 
Design 
HTML/CSS 
Component 
Business 
Logic 
Inefficient 
Static HTML being 
handed over… 
Front-end Developer 
– HTML 
– CSS/JS 
Java Developer 
– Java/OSGi 
– Business logic
Development Workflow 
Improves project efficiency by removing the pain of 
JSP and Java development 
Adobe Experience Manager 
Design 
HTML/CSS 
Component 
Business 
Logic 
Front-end Developer 
– HTML 
– CSS/JS 
Java Developer 
– Java/OSGi 
– Business logic 
Efficient 
APIs to OSGi bundles
Development Workflow 
Can be edited by front-end developers: 
✓ Client Libraries (CSS & JS) 
✕ JSP (markup & logic) 
Adobe Experience Manager 
Component
Development Workflow 
Can be edited by front-end developers: 
✓ Client Libraries (CSS & JS) 
✕ JSP (markup & logic) 
✓ HTML markup (Sightly template) 
✓ View logic (server-side JS or Java) 
Adobe Experience Manager 
Component
Sightly basic example 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a>
Sightly basic example 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a> 
1︎ 
2︎ 3︎ 
1︎ Automatic contextual HTML escaping and XSS protection of all variables 
2︎ Fallback value if property is empty 
3︎ Remove HTML attribute if value is empty
Sightly basic example 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a>
Sightly VS JSP 
Sightly 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
JSP – Scriptlets 
Adobe Experience Manager 
${properties.jcr:description} 
</a> 
<%@include file="/libs/foundation/global.jsp"%> 
<a href="<%= xssAPI.getValidHref(properties.get("link", "#")) %>" <% 
String title = properties.get("jcr:title", ""); 
if (title.length() > 0) { 
%>title="<%= xssAPI.encodeForHTMLAttr(title) %>"<% 
} %>> 
<%= xssAPI.encodeForHTML(properties.get("jcr:description", "")) %> 
</a> 
Please try again…
Sightly 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a> 
JSP – Expression Language & JSTL 
<%@include file="/libs/foundation/global.jsp"%> 
<a href="${!empty properties.link ? xss:href(properties.link) : '#'}" 
<c:if test="${!empty properties['jcr:title']}"> 
title="${xss:attr(properties['jcr:title'])}" 
</c:if> 
> 
${xss:text(properties['jcr:description'])} 
</a> 
Still complex 
Sightly VS JSP 
No automatic security
Sightly 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a> 
JSP – Custom Tag Libraries 
<%@include file="/libs/foundation/global.jsp"%> 
<a href="<out:href property='link' default='#'/>" 
No automatic security 
<c:if test="${!empty properties['jcr:title']}"> 
title="<out:attr property='jcr:title'/>" 
</c:if> 
> 
<out:text property='jcr:description'/> 
</a> 
Many tags within tags 
Sightly VS JSP
Sightly 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a> 
JSP – TagLibs for whole HTML elements 
<%@include file="/libs/foundation/global.jsp"%> 
<my:link 
urlProperty="link" 
urlDefault="#" 
titleProperty="jcr:title"> 
<my:text property="jcr:description"/> 
</my:link> 
What does it really do? 
Sightly VS JSP
Sightly 
<a href="${properties.link || '#'}" title="${properties.jcr:title}"> 
Adobe Experience Manager 
${properties.jcr:description} 
</a> 
Readable 
Explicit 
Secure 
Sightly FTW!
Adobe Experience Manager 
§ 1 Why Sightly 
§ 2 Features 
§ 3 Tooling
Building Blocks 
Comments 
<!--/* This will disappear from the output */--> 
Expression Language 
${properties.myProperty} 
Block Statements 
<div data-sly-include="other-template.html"></div> 
Adobe Experience Manager
Expressions 
• Literals 
• Variables 
• Bindings 
• Operators 
• Options 
• Contexts 
Adobe Experience Manager
Expressions 
To avoid malformed HTML, expressions can only be used 
in attribute values, in element content, or in comments. 
<!-- ${component.path} --> 
<a href="${properties.link}"> 
${properties.jcr:description} 
</a> 
For setting element or attribute names, see the element and 
attribute block statements. 
Standard bindings are available (same variables as in JSP); 
see the list of available variables. 
Adobe Experience Manager
Expression Fundamentals 
Literals (positive integers, booleans, strings, arrays) 
${42} 
${true} ${false} 
${'Hello World'} ${"Hello World"} 
${[1, 2, 3]} ${[42, true, 'Hello World']} 
Variables (and accessing object properties) 
${myVar} 
${properties.propName} 
${properties.jcr:title} 
${properties['my property']} 
${properties[myVar]} 
Adobe Experience Manager
Expression Bindings 
Most useful available variables 
${properties} 
${pageProperties} 
${inheritedPageProperties} 
${request} The Sling Request API 
${resource} The Sling Resource API 
${currentPage} The WCM Page API 
${currentDesign} The WCM Design API 
${component} The WCM Component API 
${wcmmode} The WCM Mode – use it like that: ${wcmmode.edit} 
Adobe Experience Manager 
Properties of the resource, page or inherited 
from the page structure. Access properties with 
the dot notation: ${properties.foo} 
To avoid complex expressions 
in templates, Sightly doesn’t 
support passing arguments. So 
only zero argument methods can 
be called from the template.
Expression Operators 
Logical operations (not, and, or) 
${!myVar} 
${conditionOne || conditionTwo} 
${conditionOne && conditionTwo} 
Equality / Inequality (only for same types) 
${varOne == varTwo} ${varOne != varTwo} 
Comparison (only for integers) 
${varOne < varTwo} ${varOne > varTwo} 
${varOne <= varTwo} ${varOne >= varTwo} 
Adobe Experience Manager
Expression Operators 
Conditional 
${myChoice ? varOne : varTwo} 
Grouping 
${varOne && (varTwo || varThree)} 
Adobe Experience Manager
Expression Options 
Options allow to manipulate the result of an expression, 
or to pass parameters to a block statement. 
Everything after the @ are comma separated options 
${myVar @ optOne, optTwo} 
Options can have a value (literals or variables) 
${myVar @ optOne='value', optTwo=[1, 2, 3]} 
Parametric expression (containing only options) 
${@ optOne='value', optTwo=[1, 2, 3]} 
Adobe Experience Manager
Expression Options 
String formatting 
${'Page {0} of {1}' @ format=[current, total]} 
Internationalization 
${'Page' @ i18n} 
${'Page' @ i18n, hint='Translation Hint'} 
${'Page' @ i18n, locale='en-US'} 
Array Join 
${['one', 'two'] @ join='; '} 
Adobe Experience Manager
Display Context Option 
The context option offers control over escaping and XSS protection. 
Allowing some HTML markup (filtering out scripts) 
<div>${properties.jcr:description @ context='html'}</div> 
Adding URI validation protection to other attributes than src or href 
<p data-link="${link @ context='uri'}">text</p> 
Adobe Experience Manager
Display Context Option 
<a href="${myLink}" title="${myTitle}">${myContent}</a> 
<script> var foo = "${myVar @ context='scriptString'}"; </string> 
<style> a { font-family: "${myFont @ context='styleString'}"; } </style> 
Most useful contexts and what they do: 
number XSSAPI.getValidNumber 
uri XSSAPI.getValidHref (default for src and href attributes) 
attribute XSSAPI.encodeForHTMLAttribute (default for other attributes) 
text XSSAPI.encodeForHTML (default for element content) 
scriptString XSSAPI.encodeForJSString 
styleString XSSAPI.encodeForCSSString 
html XSSAPI.filterHTML 
unsafe disables all protection, use at your own risk. 
safer 
Adobe Experience Manager
Display Context Option 
<a href="${myLink}" title="${myTitle}">${myContent}</a> 
<script> var foo = "${myVar @ context='scriptString'}"; </string> 
<style> a { font-family: "${myFont @ context='styleString'}"; } </style> 
Preferred method for each context: 
– src and href attributes: number, uri, attribute, unsafe 
– other attributes: number, uri, attribute, unsafe 
– element content: number, text, html, unsafe 
– JS scripts ⊛: number, uri, scriptString, unsafe 
– CSS styles ⊛: number, uri, styleString, unsafe 
⊛ An explicit context is required for script and style contexts. 
Don’t set the context manually unless you understand what you are doing. 
Adobe Experience Manager
Block Statements 
• Markup Inclusion: Include, Resource 
• Control Flow: Test, List, Template, Call 
• Markup Modification: Unwrap, Element, Attribute, Text 
• Object Initialization: Use 
Adobe Experience Manager
Block Statements 
To keep the markup valid, block statements are defined 
by data-sly-* attributes that can be added to any HTML 
element of the markup. 
Block statements can have 
no value, a static value, or 
an expression. 
<input data-sly-STATEMENT="foo"/> 
<div data-sly-STATEMENT.identifier="${bar}"> 
<p>Example</p> 
</div> 
Despite using data attributes, this is all executed on the 
server, and no data-sly-* attribute is sent to the client. 
Adobe Experience Manager 
What follows the dot declares an identifier to control 
how the result of the statement gets exposed.
Include Statement 
Includes the rendering of the indicated template (Sightly, JSP, ESP, etc.) 
<section data-sly-include="other-template.html"></section> 
Output: 
<section><!-- Result of the rendered script --></section> 
Adobe Experience Manager
Resource Statement 
Includes the result of the indicated resource. 
<article data-sly-resource="path/to/resource"></article> 
Output: 
<article><!-- Result of the rendered resource --></article> 
Adobe Experience Manager
Resource Statement Options 
Manipulating selectors (selectors, addSelectors, removeSelectors) 
<article data-sly-resource="${'path/to/resource' @ 
selectors='mobile'}"></article> 
Overriding the resource type 
<article data-sly-resource="${'path/to/resource' @ 
resourceType='my/resource/type'}"></article> 
Changing WCM mode 
<article data-sly-resource="${'path/to/resource' @ 
wcmmode='disabled'}"></article> 
Adobe Experience Manager
Test Statement 
Conditionally displays or removes the element and it's content. 
<p data-sly-test="${properties.showText}">text</p> 
Output: 
<p>text</p> … or nothing 
Adobe Experience Manager
The result of a test statement can be assigned to an identifier and 
reused; e.g. for something similar to an else statement. 
<p data-sly-test.show="${properties.showText}">text</p> 
<p data-sly-test="${!show}">No text</p> 
Output: 
<p>text</p> … or nothing 
Adobe Experience Manager 
The identifier declares a variable that 
holds the result of the test statement. 
Test Statement 
=
List Statement 
Repeats the content for each enumerable item. 
<ol data-sly-list="${currentPage.listChildren}"> 
<li>${itemList.count}: ${item.title}</li> 
</ol> 
Output: 
<ol> 
<li>1: Triangle Page</li> 
<li>2: Square Page</li> 
</ol> 
Adobe Experience Manager 
In that example, 
the item object 
is a Page object. 
itemList has following members: 
index: zero-based counter. 
count: one-based counter. 
first: true for the first item. 
middle: true when not first or last. 
last: true for the last item. 
odd: true if index is odd. 
even: true if index is even.
List Statement 
With the block statement dot notation, the item* variables can also 
be named explicitly, which can be useful for nested lists. 
<ol data-sly-list.child="${currentPage.listChildren}"> 
<li>${childList.count}: ${child.title}</li> 
</ol> 
Output: 
<ol> 
<li>1: Triangle Page</li> 
<li>2: Square Page</li> 
</ol> 
Adobe Experience Manager
Template & Call Statements 
Declare and call a markup snippet with named parameters. 
<template data-sly-template.foo="${@ class, text}"> 
<span class="${class}">${text}</span> 
</template> 
<div data-sly-call="${foo @ class='example', 
Adobe Experience Manager 
text='Hi'}"></div> 
Output: 
<div><span class="example">Hi</span></div>
Template & Call Statements 
Declaring template name Defining template parameters 
Declare and call a markup snippet with named parameters. 
<template data-sly-template.foo="${@ class, text}"> 
<span class="${class}">${text}</span> 
</template> 
<div data-sly-call="${foo @ class='example', 
Adobe Experience Manager 
text='Hi'}"></div> 
Output: 
<div><span class="example">Hi</span></div> 
Template content 
Calling template by name 
Passing named parameters
Template & Call Statements 
Advanced example of a recursive site map with template, call and list. 
<ol data-sly-template.listChildren="${@ page}" 
data-sly-list="${page.listChildren}"> 
<li> 
Adobe Experience Manager 
<div class="title">${item.title}</div> 
<ol data-sly-call="${listChildren @ page=item}"></ol> 
</li> 
</ol> 
<ol data-sly-call="${listChildren @ page=currentPage}"></ol>
Unwrap Statement 
Removes the host element while retaining its content. 
<div data-sly-test="${properties.showText}" 
Adobe Experience Manager 
data-sly-unwrap>text</div> 
Output: 
text … or nothing 
Use unwrap only when there’s no other way to write your template: 
prefer as much as possible to add statements on existing elements 
than to add elements for the sightly statements and removing them 
again with unwrap. This will help making the template look as close as 
possible to the generated output.
Unwrap Statement 
Unwrap can also conditionally remove the outer element. 
<div class="editable" data-sly-unwrap="${!wcmmode.edit}"> 
text 
</div> 
Output in edit mode: 
<div class="editable"> 
text 
</div> 
Output on publish: 
text 
Adobe Experience Manager
Element Statement 
Changes the name of the current element. 
<h1 data-sly-element="${titleElement}">Title</h1> 
Output: 
<h3>Title</h3> 
There’s a whitelisted number of allowed elements that can be used. 
This security can be disabled with the @ context='unsafe' option. 
Use element with care as it allows to define parts of the markup from 
the logic, which can lessen the separation of concerns. 
Adobe Experience Manager
Attribute Statement 
Sets multiple attributes to the current element. 
<input data-sly-attribute="${keyValueMapOfAttributes}"/> 
Output: 
<input type="text" name="firstName" value="Alison"/> 
Use attribute with care as it allows to define parts of the markup from 
the logic, which can lessen the separation of concerns. 
Adobe Experience Manager
Attribute Statement 
The attribute statement can be used with an identifier to indicate 
one single attribute to set/overwrite. 
<a href="#" data-sly-attribute.href="${link}">link</a> 
Would have been equivalent to: 
<a href="${link}">link</a> 
Output: 
<a href="link.html">link</a> 
But the first example is valid HTML5, while second one fails the W3C 
HTML5 validation, because the expression is an invalid URL path. 
Adobe Experience Manager
Text Statement 
Replaces the content of the element with the provided text. 
<div data-sly-text="${content}">Lorem ipsum</div> 
Would have been equivalent to: 
<div>${content}</div> 
Output: 
<div>Hello World</div> 
The text statement can be interesting to “annotate” with behavior a 
static HTML that has been handed over by a designer, while keeping it 
visually unchanged when the file is opened in a browser. 
Adobe Experience Manager
Use Statement 
Initializes a helper object. 
<div data-sly-use.logic="logic.js">${logic.hi}</div> 
Output: 
<div>Hello World</div> 
Adobe Experience Manager
Server-side JavaScript logic 
<!-- template.html --> 
<div data-sly-use.logic="logic.js">${logic.hi}</div> 
/* logic.js */ 
use(function () { 
return { 
Adobe Experience Manager 
hi: "Hello World" 
}; 
}); 
Like for the Sightly template, the objects available in the logic file are 
the same ones as in JSP with global.jsp
<!-- template.html --> 
<div data-sly-use.logic="Logic">${logic.hi}</div> 
/* Logic.java in component */ 
package apps.my_site.components.my_component; 
import com.adobe.cq.sightly.WCMUse; 
public class Logic extends WCMUse { 
private String hi; 
@Override 
public void activate() throws Exception { 
Adobe Experience Manager 
hi = "Hello World"; 
} 
public String getHi() { 
return hi; 
} 
} 
Java logic 
When the Java files are 
located in the content 
repository, next to the 
Sightly template, only 
the class name is 
needed. 
POJO extending WCMUse
<!-- template.html --> 
<div data-sly-use.logic="com.foo.Logic">${logic.hi}</div> 
/* Logic.java in OSGi bundle */ 
package com.foo; 
import javax.annotation.PostConstruct; 
import org.apache.sling.api.resource.Resource; 
import org.apache.sling.models.annotations.Model; 
@Model(adaptables = Resource.class) 
public class Logic { 
private String hi; 
@PostConstruct 
protected void init() { 
Adobe Experience Manager 
hi = "Hello World"; 
} 
public String getHi() { 
return hi; 
} 
} 
Java logic 
Adaptable with SlingModels 
When embedded in 
an OSGi bundle, the 
fully qualified Java 
class name is needed. 
The Use-API accepts classes that are 
adaptable from Resource or Request.
What kind of Use-API? 
Model logic 
This logic is not tied to a template and is potentially reusable among components. 
It should aim to form a stable API that changes little, even in case of a full redesign. 
➔ Java located in OSGi bundle 
View logic 
This logic is specific to the templates and is likely to change if the design changes. 
It is thus a good practice to locate it in the content repository, next to the template. 
➔ JavaScript located in component 
If components are to be maintained by front-end devs (typically with Brackets). 
➔ Java located in component 
If performance is critical (e.g. when many requests are not cached by the dispatcher). 
Adobe Experience Manager
Start simple: first, no code! 
Resource Template 
sling: 
resourceType 
Content Structure Component (View) 
Adobe Experience Manager 
OSGi (Model) 
Resource 
API 
Page 
API 
Content Repository 
– Sling plays the role of the controller 
and resolves the sling:resourceType, 
deciding which component will 
render the accessed resource. 
– The component plays the role of the 
view and it’s Sightly template builds 
the corresponding markup. 
– The Resource and Page APIs play 
the role of the model, which are 
available from the template as 
variables.
Add logic only where needed 
Resource Template View Logic 
sling: 
resourceType data-sly-use 
Content Structure Component (View) 
Adobe Experience Manager 
– Model Logic is 
needed only if the 
logic to access the 
data is different to 
what existing APIs 
provide. 
– View Logic is 
needed only when 
the template needs 
additional data 
preparation. 
OSGi (Model) 
Resource 
API 
Page 
API 
Model Logic 
Content Repository
Use-API Bindings 
The logic can access the same variables than exist in the template. 
JavaScript: 
var title = properties.get('title'); 
Java extending WCMUse: 
String title = getProperties().get("title", String.class); 
Java with SlingModels: 
@Inject @Optional 
private String title; 
Adobe Experience Manager
Use-API Parameters 
With the same notation as for template parameters, named 
parameters can be passed to the Use-API. 
<a data-sly-use.ext="${'Externalize' @ path='page.html'}" 
href="${ext.absolutePath}">link</a> 
Output: 
<a href="/absolute/path/to/page.html">link</a> 
Don’t pass variables that are part of the global binding (like properties 
or resource) as they can be accessed from the logic too. 
Adobe Experience Manager
Use-API Parameters 
These parameters can then be read in from the various Use-API. 
JavaScript: 
var path = this.path; 
Java extending WCMUse: 
String path = get("path", String.class); 
Java with SlingModels (works only when adapting from Request): 
@Inject @Optional 
private String path; 
Adobe Experience Manager
Use with Template & Call 
The use statement can also load data-sly-template markup 
snippets located in other files. 
<!-- library.html --> 
<template data-sly-template.foo="${@ text}"> 
<span class="example">${text}</span> 
</template> 
<!-- template.html --> 
<div data-sly-use.library="library.html" 
Adobe Experience Manager 
data-sly-call="${library.foo @ text='Hi'}"></div> 
Output: 
<div><span class="example">Hi</span></div>
Adobe Experience Manager 
Sightly Don’ts 
• Don’t use the option context="unsafe", unless there’s no other 
choice. When doing so, carefully assess the consequences. 
• Don’t use data-sly-unwrap if there’s another HTML element on 
which you can put the Sightly instructions. 
• Avoid to use data-sly-element and data-sly-attribute in a 
way that makes the logic define parts of the generated markup.
Adobe Experience Manager 
Sightly FAQ 
What does Sightly enable that isn’t possible with JSP? 
– Systematic state-of-the-art protection against cross-site scripting injection. 
– Possibility for front-end developers to easily participate on AEM projects. 
– Strictly enforced separation of concern, yet with flexible binding for logic. 
– Tailored to the Sling use-case. 
Should JSPs be refactored to Sightly? 
Refactoring can be expensive, which goes against the goal of Sightly to increase 
development efficiency. If the quality of existing JSPs is sufficient, it is rather advised 
to use Sightly for newly built/improved components. 
Will JSP go away? 
As of today, there are no plans for that.
Adobe Experience Manager 
§ 1 Why Sightly 
§ 2 Features 
§ 3 Tooling
IDE & Developer Mode 
• Improve learning curve and efficiency of developers 
• An IDE plugin for each developer role 
Adobe Experience Manager 
Brackets plugin 
for the Front-End developers 
http://docs.adobe.com/docs/en/dev-tools/sightly-brackets.html 
Eclipse plugin 
for the Java developers 
http://docs.adobe.com/docs/en/dev-tools/aem-eclipse.html
Work on file system + transparent sync & content editing 
Adobe Experience Manager 
IDE Sync 
Version Control 
System (Git / Svn) File System 
Content 
Repository 
sync 
manual pull 
Brackets / Eclipse 
IDE 
auto push 
IDE works on 
the File System
Adobe Experience Manager 
Thank you! 
Sightly 
– Documentation 
– Specification 
– Sightly AEM Page Example (requires instance on localhost:4502) 
– TodoMVC Example 
Tools 
– Live Sightly execution environment 
– Sightly Brackets extension 
– AEM Developer Tools for Eclipse 
– AEM Developer Mode
AEM Sightly Template Language

More Related Content

What's hot

Rest and Sling Resolution
Rest and Sling ResolutionRest and Sling Resolution
Rest and Sling Resolution
DEEPAK KHETAWAT
 
Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson
AEM HUB
 

What's hot (20)

Understanding Sling Models in AEM
Understanding Sling Models in AEMUnderstanding Sling Models in AEM
Understanding Sling Models in AEM
 
AEM (CQ) Dispatcher Security and CDN+Browser Caching
AEM (CQ) Dispatcher Security and CDN+Browser CachingAEM (CQ) Dispatcher Security and CDN+Browser Caching
AEM (CQ) Dispatcher Security and CDN+Browser Caching
 
SPA Editor - Adobe Experience Manager Sites
SPA Editor - Adobe Experience Manager SitesSPA Editor - Adobe Experience Manager Sites
SPA Editor - Adobe Experience Manager Sites
 
Sling Models Overview
Sling Models OverviewSling Models Overview
Sling Models Overview
 
Sightly - Part 2
Sightly - Part 2Sightly - Part 2
Sightly - Part 2
 
AEM - Client Libraries
AEM - Client LibrariesAEM - Client Libraries
AEM - Client Libraries
 
slingmodels
slingmodelsslingmodels
slingmodels
 
Adobe AEM core components
Adobe AEM core componentsAdobe AEM core components
Adobe AEM core components
 
Cascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) helpCascading Style Sheets (CSS) help
Cascading Style Sheets (CSS) help
 
Rest and Sling Resolution
Rest and Sling ResolutionRest and Sling Resolution
Rest and Sling Resolution
 
JCR, Sling or AEM? Which API should I use and when?
JCR, Sling or AEM? Which API should I use and when?JCR, Sling or AEM? Which API should I use and when?
JCR, Sling or AEM? Which API should I use and when?
 
Experience and Content Fragment
Experience and Content FragmentExperience and Content Fragment
Experience and Content Fragment
 
Integration patterns in AEM 6
Integration patterns in AEM 6Integration patterns in AEM 6
Integration patterns in AEM 6
 
AEM Meetup Personalization with ContextHub
AEM Meetup Personalization with ContextHubAEM Meetup Personalization with ContextHub
AEM Meetup Personalization with ContextHub
 
IMMERSE 2016 Introducing content fragments
IMMERSE 2016 Introducing content fragmentsIMMERSE 2016 Introducing content fragments
IMMERSE 2016 Introducing content fragments
 
Aem dispatcher – tips & tricks
Aem dispatcher – tips & tricksAem dispatcher – tips & tricks
Aem dispatcher – tips & tricks
 
Media queries A to Z
Media queries A to ZMedia queries A to Z
Media queries A to Z
 
Introduction to Sightly
Introduction to SightlyIntroduction to Sightly
Introduction to Sightly
 
Sling models by Justin Edelson
Sling models by Justin Edelson Sling models by Justin Edelson
Sling models by Justin Edelson
 
The secret life of a dispatcher (Adobe CQ AEM)
The secret life of a dispatcher (Adobe CQ AEM)The secret life of a dispatcher (Adobe CQ AEM)
The secret life of a dispatcher (Adobe CQ AEM)
 

Viewers also liked

Build single page applications using AngularJS on AEM
Build single page applications using AngularJS on AEMBuild single page applications using AngularJS on AEM
Build single page applications using AngularJS on AEM
connectwebex
 
Microservices Architecture for AEM
Microservices Architecture for AEMMicroservices Architecture for AEM
Microservices Architecture for AEM
Maciej Majchrzak
 
Four approaches to integrate aem with external systems by Jan Kuzniak
Four approaches to integrate aem with external systems by Jan KuzniakFour approaches to integrate aem with external systems by Jan Kuzniak
Four approaches to integrate aem with external systems by Jan Kuzniak
AEM HUB
 

Viewers also liked (17)

The six key steps to AEM architecture
The six key steps to AEM architectureThe six key steps to AEM architecture
The six key steps to AEM architecture
 
Sling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak KhetawatSling Models Using Sightly and JSP by Deepak Khetawat
Sling Models Using Sightly and JSP by Deepak Khetawat
 
Build single page applications using AngularJS on AEM
Build single page applications using AngularJS on AEMBuild single page applications using AngularJS on AEM
Build single page applications using AngularJS on AEM
 
AEM 6.1 User Interface Customization
AEM 6.1 User Interface CustomizationAEM 6.1 User Interface Customization
AEM 6.1 User Interface Customization
 
Dynamic components using SPA concepts in AEM
Dynamic components using SPA concepts in AEMDynamic components using SPA concepts in AEM
Dynamic components using SPA concepts in AEM
 
Aem best practices
Aem best practicesAem best practices
Aem best practices
 
AEM (CQ) Dispatcher Caching Webinar 2013
AEM (CQ) Dispatcher Caching Webinar 2013AEM (CQ) Dispatcher Caching Webinar 2013
AEM (CQ) Dispatcher Caching Webinar 2013
 
Adobe Experience Manager Vision and Roadmap
Adobe Experience Manager Vision and RoadmapAdobe Experience Manager Vision and Roadmap
Adobe Experience Manager Vision and Roadmap
 
Adobe Meetup AEM Architecture Sydney 2015
Adobe Meetup AEM Architecture Sydney 2015Adobe Meetup AEM Architecture Sydney 2015
Adobe Meetup AEM Architecture Sydney 2015
 
Microservices Architecture for AEM
Microservices Architecture for AEMMicroservices Architecture for AEM
Microservices Architecture for AEM
 
Four approaches to integrate aem with external systems by Jan Kuzniak
Four approaches to integrate aem with external systems by Jan KuzniakFour approaches to integrate aem with external systems by Jan Kuzniak
Four approaches to integrate aem with external systems by Jan Kuzniak
 
AEM GEMS Session SAML authentication in AEM
AEM GEMS Session SAML authentication in AEMAEM GEMS Session SAML authentication in AEM
AEM GEMS Session SAML authentication in AEM
 
Thoughts on Component Resuse
Thoughts on Component ResuseThoughts on Component Resuse
Thoughts on Component Resuse
 
Accelerate Your Next AEM Project
Accelerate Your Next AEM ProjectAccelerate Your Next AEM Project
Accelerate Your Next AEM Project
 
Sling Component Filters in CQ5
Sling Component Filters in CQ5 Sling Component Filters in CQ5
Sling Component Filters in CQ5
 
Haack Lander @ Tech Summit PR 2015
Haack Lander @ Tech Summit PR 2015Haack Lander @ Tech Summit PR 2015
Haack Lander @ Tech Summit PR 2015
 
Continous Delivery with CQ
Continous Delivery with CQContinous Delivery with CQ
Continous Delivery with CQ
 

Similar to AEM Sightly Template Language

Ruby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayConRuby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayCon
heikowebers
 

Similar to AEM Sightly Template Language (20)

EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component DevelopmentEVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
EVOLVE'14 | Enhance | Gabriel Walt | Sightly Component Development
 
Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101Geek Moot '09 -- Smarty 101
Geek Moot '09 -- Smarty 101
 
前端概述
前端概述前端概述
前端概述
 
Basics of Java Script (JS)
Basics of Java Script (JS)Basics of Java Script (JS)
Basics of Java Script (JS)
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Html JavaScript and CSS
Html JavaScript and CSSHtml JavaScript and CSS
Html JavaScript and CSS
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
The Django Web Application Framework 2
The Django Web Application Framework 2The Django Web Application Framework 2
The Django Web Application Framework 2
 
Struts 2
Struts 2Struts 2
Struts 2
 
Wt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technologyWt unit 2 ppts client sied technology
Wt unit 2 ppts client sied technology
 
Wt unit 2 ppts client side technology
Wt unit 2 ppts client side technologyWt unit 2 ppts client side technology
Wt unit 2 ppts client side technology
 
Working with Javascript in Rails
Working with Javascript in RailsWorking with Javascript in Rails
Working with Javascript in Rails
 
The Rails Way
The Rails WayThe Rails Way
The Rails Way
 
Web performance essentials - Goodies
Web performance essentials - GoodiesWeb performance essentials - Goodies
Web performance essentials - Goodies
 
Building Potent WordPress Websites
Building Potent WordPress WebsitesBuilding Potent WordPress Websites
Building Potent WordPress Websites
 
Angular.js Fundamentals
Angular.js FundamentalsAngular.js Fundamentals
Angular.js Fundamentals
 
Angular JS2 Training Session #1
Angular JS2 Training Session #1Angular JS2 Training Session #1
Angular JS2 Training Session #1
 
Ruby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayConRuby on Rails Security Updated (Rails 3) at RailsWayCon
Ruby on Rails Security Updated (Rails 3) at RailsWayCon
 
Ams adapters
Ams adaptersAms adapters
Ams adapters
 

More from Gabriel Walt

Three WEM Dev Tricks
Three WEM Dev TricksThree WEM Dev Tricks
Three WEM Dev Tricks
Gabriel Walt
 

More from Gabriel Walt (11)

Managing Omnichannel Experiences with Adobe Experience Manager (AEM)
Managing Omnichannel Experiences with Adobe Experience Manager (AEM)Managing Omnichannel Experiences with Adobe Experience Manager (AEM)
Managing Omnichannel Experiences with Adobe Experience Manager (AEM)
 
Modernizing Adobe Experience Manager (AEM)
Modernizing Adobe Experience Manager (AEM)Modernizing Adobe Experience Manager (AEM)
Modernizing Adobe Experience Manager (AEM)
 
Adobe Experience Manager Core Components
Adobe Experience Manager Core ComponentsAdobe Experience Manager Core Components
Adobe Experience Manager Core Components
 
CQ Provisionning & Authoring
CQ Provisionning & AuthoringCQ Provisionning & Authoring
CQ Provisionning & Authoring
 
Web, Mobile, App and Back!
Web, Mobile, App and Back!Web, Mobile, App and Back!
Web, Mobile, App and Back!
 
Drive dam
Drive damDrive dam
Drive dam
 
Optimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEMOptimizing HTML5 Sites with CQ5/WEM
Optimizing HTML5 Sites with CQ5/WEM
 
CQ 5.4 Deep-Dive
CQ 5.4 Deep-DiveCQ 5.4 Deep-Dive
CQ 5.4 Deep-Dive
 
Crx 2.2 Deep-Dive
Crx 2.2 Deep-DiveCrx 2.2 Deep-Dive
Crx 2.2 Deep-Dive
 
Three WEM Dev Tricks
Three WEM Dev TricksThree WEM Dev Tricks
Three WEM Dev Tricks
 
Web Apps atop a Content Repository
Web Apps atop a Content RepositoryWeb Apps atop a Content Repository
Web Apps atop a Content Repository
 

Recently uploaded

Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
panagenda
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 

Recently uploaded (20)

Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
Why Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire businessWhy Teams call analytics are critical to your entire business
Why Teams call analytics are critical to your entire business
 
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWEREMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
EMPOWERMENT TECHNOLOGY GRADE 11 QUARTER 2 REVIEWER
 
Real Time Object Detection Using Open CV
Real Time Object Detection Using Open CVReal Time Object Detection Using Open CV
Real Time Object Detection Using Open CV
 
Automating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps ScriptAutomating Google Workspace (GWS) & more with Apps Script
Automating Google Workspace (GWS) & more with Apps Script
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?A Year of the Servo Reboot: Where Are We Now?
A Year of the Servo Reboot: Where Are We Now?
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
A Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source MilvusA Beginners Guide to Building a RAG App Using Open Source Milvus
A Beginners Guide to Building a RAG App Using Open Source Milvus
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
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
 
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu SubbuApidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
Apidays Singapore 2024 - Modernizing Securities Finance by Madhu Subbu
 
presentation ICT roal in 21st century education
presentation ICT roal in 21st century educationpresentation ICT roal in 21st century education
presentation ICT roal in 21st century education
 
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
Emergent Methods: Multi-lingual narrative tracking in the news - real-time ex...
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024Manulife - Insurer Transformation Award 2024
Manulife - Insurer Transformation Award 2024
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
Web Form Automation for Bonterra Impact Management (fka Social Solutions Apri...
 
MS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectorsMS Copilot expands with MS Graph connectors
MS Copilot expands with MS Graph connectors
 

AEM Sightly Template Language

  • 1. AEM6+ Component Development Adobe Experience Manager @GabrielWalt, Product Manager
  • 2. Specification and TCK open sourced to GitHub. Reference implementation donated to Apache Sling. Follow @sightlyio on Twitter. http://docs.adobe.com/docs/en/aem/6-0/develop/sightly.html Adobe Experience Manager
  • 3. Adobe Experience Manager § 1 Why Sightly § 2 Features § 3 Tooling
  • 4. Project Efficiency Adobe.com estimated that it reduced their project costs by about 25% JSP Project Adobe Experience Manager Design HTML/CSS Template JSP Logic Java Design HTML/CSS Template Sightly HTML Logic Use-API Project Management Sightly Management ~25% Effort / Cost
  • 5. Development Workflow Improves project efficiency by removing the pain of JSP and Java development Adobe Experience Manager Design HTML/CSS Component Business Logic Inefficient Static HTML being handed over… Front-end Developer – HTML – CSS/JS Java Developer – Java/OSGi – Business logic
  • 6. Development Workflow Improves project efficiency by removing the pain of JSP and Java development Adobe Experience Manager Design HTML/CSS Component Business Logic Front-end Developer – HTML – CSS/JS Java Developer – Java/OSGi – Business logic Efficient APIs to OSGi bundles
  • 7. Development Workflow Can be edited by front-end developers: ✓ Client Libraries (CSS & JS) ✕ JSP (markup & logic) Adobe Experience Manager Component
  • 8. Development Workflow Can be edited by front-end developers: ✓ Client Libraries (CSS & JS) ✕ JSP (markup & logic) ✓ HTML markup (Sightly template) ✓ View logic (server-side JS or Java) Adobe Experience Manager Component
  • 9. Sightly basic example <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a>
  • 10. Sightly basic example <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a> 1︎ 2︎ 3︎ 1︎ Automatic contextual HTML escaping and XSS protection of all variables 2︎ Fallback value if property is empty 3︎ Remove HTML attribute if value is empty
  • 11. Sightly basic example <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a>
  • 12. Sightly VS JSP Sightly <a href="${properties.link || '#'}" title="${properties.jcr:title}"> JSP – Scriptlets Adobe Experience Manager ${properties.jcr:description} </a> <%@include file="/libs/foundation/global.jsp"%> <a href="<%= xssAPI.getValidHref(properties.get("link", "#")) %>" <% String title = properties.get("jcr:title", ""); if (title.length() > 0) { %>title="<%= xssAPI.encodeForHTMLAttr(title) %>"<% } %>> <%= xssAPI.encodeForHTML(properties.get("jcr:description", "")) %> </a> Please try again…
  • 13. Sightly <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a> JSP – Expression Language & JSTL <%@include file="/libs/foundation/global.jsp"%> <a href="${!empty properties.link ? xss:href(properties.link) : '#'}" <c:if test="${!empty properties['jcr:title']}"> title="${xss:attr(properties['jcr:title'])}" </c:if> > ${xss:text(properties['jcr:description'])} </a> Still complex Sightly VS JSP No automatic security
  • 14. Sightly <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a> JSP – Custom Tag Libraries <%@include file="/libs/foundation/global.jsp"%> <a href="<out:href property='link' default='#'/>" No automatic security <c:if test="${!empty properties['jcr:title']}"> title="<out:attr property='jcr:title'/>" </c:if> > <out:text property='jcr:description'/> </a> Many tags within tags Sightly VS JSP
  • 15. Sightly <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a> JSP – TagLibs for whole HTML elements <%@include file="/libs/foundation/global.jsp"%> <my:link urlProperty="link" urlDefault="#" titleProperty="jcr:title"> <my:text property="jcr:description"/> </my:link> What does it really do? Sightly VS JSP
  • 16. Sightly <a href="${properties.link || '#'}" title="${properties.jcr:title}"> Adobe Experience Manager ${properties.jcr:description} </a> Readable Explicit Secure Sightly FTW!
  • 17. Adobe Experience Manager § 1 Why Sightly § 2 Features § 3 Tooling
  • 18. Building Blocks Comments <!--/* This will disappear from the output */--> Expression Language ${properties.myProperty} Block Statements <div data-sly-include="other-template.html"></div> Adobe Experience Manager
  • 19. Expressions • Literals • Variables • Bindings • Operators • Options • Contexts Adobe Experience Manager
  • 20. Expressions To avoid malformed HTML, expressions can only be used in attribute values, in element content, or in comments. <!-- ${component.path} --> <a href="${properties.link}"> ${properties.jcr:description} </a> For setting element or attribute names, see the element and attribute block statements. Standard bindings are available (same variables as in JSP); see the list of available variables. Adobe Experience Manager
  • 21. Expression Fundamentals Literals (positive integers, booleans, strings, arrays) ${42} ${true} ${false} ${'Hello World'} ${"Hello World"} ${[1, 2, 3]} ${[42, true, 'Hello World']} Variables (and accessing object properties) ${myVar} ${properties.propName} ${properties.jcr:title} ${properties['my property']} ${properties[myVar]} Adobe Experience Manager
  • 22. Expression Bindings Most useful available variables ${properties} ${pageProperties} ${inheritedPageProperties} ${request} The Sling Request API ${resource} The Sling Resource API ${currentPage} The WCM Page API ${currentDesign} The WCM Design API ${component} The WCM Component API ${wcmmode} The WCM Mode – use it like that: ${wcmmode.edit} Adobe Experience Manager Properties of the resource, page or inherited from the page structure. Access properties with the dot notation: ${properties.foo} To avoid complex expressions in templates, Sightly doesn’t support passing arguments. So only zero argument methods can be called from the template.
  • 23. Expression Operators Logical operations (not, and, or) ${!myVar} ${conditionOne || conditionTwo} ${conditionOne && conditionTwo} Equality / Inequality (only for same types) ${varOne == varTwo} ${varOne != varTwo} Comparison (only for integers) ${varOne < varTwo} ${varOne > varTwo} ${varOne <= varTwo} ${varOne >= varTwo} Adobe Experience Manager
  • 24. Expression Operators Conditional ${myChoice ? varOne : varTwo} Grouping ${varOne && (varTwo || varThree)} Adobe Experience Manager
  • 25. Expression Options Options allow to manipulate the result of an expression, or to pass parameters to a block statement. Everything after the @ are comma separated options ${myVar @ optOne, optTwo} Options can have a value (literals or variables) ${myVar @ optOne='value', optTwo=[1, 2, 3]} Parametric expression (containing only options) ${@ optOne='value', optTwo=[1, 2, 3]} Adobe Experience Manager
  • 26. Expression Options String formatting ${'Page {0} of {1}' @ format=[current, total]} Internationalization ${'Page' @ i18n} ${'Page' @ i18n, hint='Translation Hint'} ${'Page' @ i18n, locale='en-US'} Array Join ${['one', 'two'] @ join='; '} Adobe Experience Manager
  • 27. Display Context Option The context option offers control over escaping and XSS protection. Allowing some HTML markup (filtering out scripts) <div>${properties.jcr:description @ context='html'}</div> Adding URI validation protection to other attributes than src or href <p data-link="${link @ context='uri'}">text</p> Adobe Experience Manager
  • 28. Display Context Option <a href="${myLink}" title="${myTitle}">${myContent}</a> <script> var foo = "${myVar @ context='scriptString'}"; </string> <style> a { font-family: "${myFont @ context='styleString'}"; } </style> Most useful contexts and what they do: number XSSAPI.getValidNumber uri XSSAPI.getValidHref (default for src and href attributes) attribute XSSAPI.encodeForHTMLAttribute (default for other attributes) text XSSAPI.encodeForHTML (default for element content) scriptString XSSAPI.encodeForJSString styleString XSSAPI.encodeForCSSString html XSSAPI.filterHTML unsafe disables all protection, use at your own risk. safer Adobe Experience Manager
  • 29. Display Context Option <a href="${myLink}" title="${myTitle}">${myContent}</a> <script> var foo = "${myVar @ context='scriptString'}"; </string> <style> a { font-family: "${myFont @ context='styleString'}"; } </style> Preferred method for each context: – src and href attributes: number, uri, attribute, unsafe – other attributes: number, uri, attribute, unsafe – element content: number, text, html, unsafe – JS scripts ⊛: number, uri, scriptString, unsafe – CSS styles ⊛: number, uri, styleString, unsafe ⊛ An explicit context is required for script and style contexts. Don’t set the context manually unless you understand what you are doing. Adobe Experience Manager
  • 30. Block Statements • Markup Inclusion: Include, Resource • Control Flow: Test, List, Template, Call • Markup Modification: Unwrap, Element, Attribute, Text • Object Initialization: Use Adobe Experience Manager
  • 31. Block Statements To keep the markup valid, block statements are defined by data-sly-* attributes that can be added to any HTML element of the markup. Block statements can have no value, a static value, or an expression. <input data-sly-STATEMENT="foo"/> <div data-sly-STATEMENT.identifier="${bar}"> <p>Example</p> </div> Despite using data attributes, this is all executed on the server, and no data-sly-* attribute is sent to the client. Adobe Experience Manager What follows the dot declares an identifier to control how the result of the statement gets exposed.
  • 32. Include Statement Includes the rendering of the indicated template (Sightly, JSP, ESP, etc.) <section data-sly-include="other-template.html"></section> Output: <section><!-- Result of the rendered script --></section> Adobe Experience Manager
  • 33. Resource Statement Includes the result of the indicated resource. <article data-sly-resource="path/to/resource"></article> Output: <article><!-- Result of the rendered resource --></article> Adobe Experience Manager
  • 34. Resource Statement Options Manipulating selectors (selectors, addSelectors, removeSelectors) <article data-sly-resource="${'path/to/resource' @ selectors='mobile'}"></article> Overriding the resource type <article data-sly-resource="${'path/to/resource' @ resourceType='my/resource/type'}"></article> Changing WCM mode <article data-sly-resource="${'path/to/resource' @ wcmmode='disabled'}"></article> Adobe Experience Manager
  • 35. Test Statement Conditionally displays or removes the element and it's content. <p data-sly-test="${properties.showText}">text</p> Output: <p>text</p> … or nothing Adobe Experience Manager
  • 36. The result of a test statement can be assigned to an identifier and reused; e.g. for something similar to an else statement. <p data-sly-test.show="${properties.showText}">text</p> <p data-sly-test="${!show}">No text</p> Output: <p>text</p> … or nothing Adobe Experience Manager The identifier declares a variable that holds the result of the test statement. Test Statement =
  • 37. List Statement Repeats the content for each enumerable item. <ol data-sly-list="${currentPage.listChildren}"> <li>${itemList.count}: ${item.title}</li> </ol> Output: <ol> <li>1: Triangle Page</li> <li>2: Square Page</li> </ol> Adobe Experience Manager In that example, the item object is a Page object. itemList has following members: index: zero-based counter. count: one-based counter. first: true for the first item. middle: true when not first or last. last: true for the last item. odd: true if index is odd. even: true if index is even.
  • 38. List Statement With the block statement dot notation, the item* variables can also be named explicitly, which can be useful for nested lists. <ol data-sly-list.child="${currentPage.listChildren}"> <li>${childList.count}: ${child.title}</li> </ol> Output: <ol> <li>1: Triangle Page</li> <li>2: Square Page</li> </ol> Adobe Experience Manager
  • 39. Template & Call Statements Declare and call a markup snippet with named parameters. <template data-sly-template.foo="${@ class, text}"> <span class="${class}">${text}</span> </template> <div data-sly-call="${foo @ class='example', Adobe Experience Manager text='Hi'}"></div> Output: <div><span class="example">Hi</span></div>
  • 40. Template & Call Statements Declaring template name Defining template parameters Declare and call a markup snippet with named parameters. <template data-sly-template.foo="${@ class, text}"> <span class="${class}">${text}</span> </template> <div data-sly-call="${foo @ class='example', Adobe Experience Manager text='Hi'}"></div> Output: <div><span class="example">Hi</span></div> Template content Calling template by name Passing named parameters
  • 41. Template & Call Statements Advanced example of a recursive site map with template, call and list. <ol data-sly-template.listChildren="${@ page}" data-sly-list="${page.listChildren}"> <li> Adobe Experience Manager <div class="title">${item.title}</div> <ol data-sly-call="${listChildren @ page=item}"></ol> </li> </ol> <ol data-sly-call="${listChildren @ page=currentPage}"></ol>
  • 42. Unwrap Statement Removes the host element while retaining its content. <div data-sly-test="${properties.showText}" Adobe Experience Manager data-sly-unwrap>text</div> Output: text … or nothing Use unwrap only when there’s no other way to write your template: prefer as much as possible to add statements on existing elements than to add elements for the sightly statements and removing them again with unwrap. This will help making the template look as close as possible to the generated output.
  • 43. Unwrap Statement Unwrap can also conditionally remove the outer element. <div class="editable" data-sly-unwrap="${!wcmmode.edit}"> text </div> Output in edit mode: <div class="editable"> text </div> Output on publish: text Adobe Experience Manager
  • 44. Element Statement Changes the name of the current element. <h1 data-sly-element="${titleElement}">Title</h1> Output: <h3>Title</h3> There’s a whitelisted number of allowed elements that can be used. This security can be disabled with the @ context='unsafe' option. Use element with care as it allows to define parts of the markup from the logic, which can lessen the separation of concerns. Adobe Experience Manager
  • 45. Attribute Statement Sets multiple attributes to the current element. <input data-sly-attribute="${keyValueMapOfAttributes}"/> Output: <input type="text" name="firstName" value="Alison"/> Use attribute with care as it allows to define parts of the markup from the logic, which can lessen the separation of concerns. Adobe Experience Manager
  • 46. Attribute Statement The attribute statement can be used with an identifier to indicate one single attribute to set/overwrite. <a href="#" data-sly-attribute.href="${link}">link</a> Would have been equivalent to: <a href="${link}">link</a> Output: <a href="link.html">link</a> But the first example is valid HTML5, while second one fails the W3C HTML5 validation, because the expression is an invalid URL path. Adobe Experience Manager
  • 47. Text Statement Replaces the content of the element with the provided text. <div data-sly-text="${content}">Lorem ipsum</div> Would have been equivalent to: <div>${content}</div> Output: <div>Hello World</div> The text statement can be interesting to “annotate” with behavior a static HTML that has been handed over by a designer, while keeping it visually unchanged when the file is opened in a browser. Adobe Experience Manager
  • 48. Use Statement Initializes a helper object. <div data-sly-use.logic="logic.js">${logic.hi}</div> Output: <div>Hello World</div> Adobe Experience Manager
  • 49. Server-side JavaScript logic <!-- template.html --> <div data-sly-use.logic="logic.js">${logic.hi}</div> /* logic.js */ use(function () { return { Adobe Experience Manager hi: "Hello World" }; }); Like for the Sightly template, the objects available in the logic file are the same ones as in JSP with global.jsp
  • 50. <!-- template.html --> <div data-sly-use.logic="Logic">${logic.hi}</div> /* Logic.java in component */ package apps.my_site.components.my_component; import com.adobe.cq.sightly.WCMUse; public class Logic extends WCMUse { private String hi; @Override public void activate() throws Exception { Adobe Experience Manager hi = "Hello World"; } public String getHi() { return hi; } } Java logic When the Java files are located in the content repository, next to the Sightly template, only the class name is needed. POJO extending WCMUse
  • 51. <!-- template.html --> <div data-sly-use.logic="com.foo.Logic">${logic.hi}</div> /* Logic.java in OSGi bundle */ package com.foo; import javax.annotation.PostConstruct; import org.apache.sling.api.resource.Resource; import org.apache.sling.models.annotations.Model; @Model(adaptables = Resource.class) public class Logic { private String hi; @PostConstruct protected void init() { Adobe Experience Manager hi = "Hello World"; } public String getHi() { return hi; } } Java logic Adaptable with SlingModels When embedded in an OSGi bundle, the fully qualified Java class name is needed. The Use-API accepts classes that are adaptable from Resource or Request.
  • 52. What kind of Use-API? Model logic This logic is not tied to a template and is potentially reusable among components. It should aim to form a stable API that changes little, even in case of a full redesign. ➔ Java located in OSGi bundle View logic This logic is specific to the templates and is likely to change if the design changes. It is thus a good practice to locate it in the content repository, next to the template. ➔ JavaScript located in component If components are to be maintained by front-end devs (typically with Brackets). ➔ Java located in component If performance is critical (e.g. when many requests are not cached by the dispatcher). Adobe Experience Manager
  • 53. Start simple: first, no code! Resource Template sling: resourceType Content Structure Component (View) Adobe Experience Manager OSGi (Model) Resource API Page API Content Repository – Sling plays the role of the controller and resolves the sling:resourceType, deciding which component will render the accessed resource. – The component plays the role of the view and it’s Sightly template builds the corresponding markup. – The Resource and Page APIs play the role of the model, which are available from the template as variables.
  • 54. Add logic only where needed Resource Template View Logic sling: resourceType data-sly-use Content Structure Component (View) Adobe Experience Manager – Model Logic is needed only if the logic to access the data is different to what existing APIs provide. – View Logic is needed only when the template needs additional data preparation. OSGi (Model) Resource API Page API Model Logic Content Repository
  • 55. Use-API Bindings The logic can access the same variables than exist in the template. JavaScript: var title = properties.get('title'); Java extending WCMUse: String title = getProperties().get("title", String.class); Java with SlingModels: @Inject @Optional private String title; Adobe Experience Manager
  • 56. Use-API Parameters With the same notation as for template parameters, named parameters can be passed to the Use-API. <a data-sly-use.ext="${'Externalize' @ path='page.html'}" href="${ext.absolutePath}">link</a> Output: <a href="/absolute/path/to/page.html">link</a> Don’t pass variables that are part of the global binding (like properties or resource) as they can be accessed from the logic too. Adobe Experience Manager
  • 57. Use-API Parameters These parameters can then be read in from the various Use-API. JavaScript: var path = this.path; Java extending WCMUse: String path = get("path", String.class); Java with SlingModels (works only when adapting from Request): @Inject @Optional private String path; Adobe Experience Manager
  • 58. Use with Template & Call The use statement can also load data-sly-template markup snippets located in other files. <!-- library.html --> <template data-sly-template.foo="${@ text}"> <span class="example">${text}</span> </template> <!-- template.html --> <div data-sly-use.library="library.html" Adobe Experience Manager data-sly-call="${library.foo @ text='Hi'}"></div> Output: <div><span class="example">Hi</span></div>
  • 59. Adobe Experience Manager Sightly Don’ts • Don’t use the option context="unsafe", unless there’s no other choice. When doing so, carefully assess the consequences. • Don’t use data-sly-unwrap if there’s another HTML element on which you can put the Sightly instructions. • Avoid to use data-sly-element and data-sly-attribute in a way that makes the logic define parts of the generated markup.
  • 60. Adobe Experience Manager Sightly FAQ What does Sightly enable that isn’t possible with JSP? – Systematic state-of-the-art protection against cross-site scripting injection. – Possibility for front-end developers to easily participate on AEM projects. – Strictly enforced separation of concern, yet with flexible binding for logic. – Tailored to the Sling use-case. Should JSPs be refactored to Sightly? Refactoring can be expensive, which goes against the goal of Sightly to increase development efficiency. If the quality of existing JSPs is sufficient, it is rather advised to use Sightly for newly built/improved components. Will JSP go away? As of today, there are no plans for that.
  • 61. Adobe Experience Manager § 1 Why Sightly § 2 Features § 3 Tooling
  • 62. IDE & Developer Mode • Improve learning curve and efficiency of developers • An IDE plugin for each developer role Adobe Experience Manager Brackets plugin for the Front-End developers http://docs.adobe.com/docs/en/dev-tools/sightly-brackets.html Eclipse plugin for the Java developers http://docs.adobe.com/docs/en/dev-tools/aem-eclipse.html
  • 63. Work on file system + transparent sync & content editing Adobe Experience Manager IDE Sync Version Control System (Git / Svn) File System Content Repository sync manual pull Brackets / Eclipse IDE auto push IDE works on the File System
  • 64. Adobe Experience Manager Thank you! Sightly – Documentation – Specification – Sightly AEM Page Example (requires instance on localhost:4502) – TodoMVC Example Tools – Live Sightly execution environment – Sightly Brackets extension – AEM Developer Tools for Eclipse – AEM Developer Mode