Beruflich Dokumente
Kultur Dokumente
Revision History
Accepted By Date
1
Adobe Experience Manager Developer Guide
Table of Contents
2
Adobe Experience Manager Developer Guide
3
Adobe Experience Manager Developer Guide
4
Adobe Experience Manager Developer Guide
AEM INTRODUCTION:
Adobe Experience Manager (AEM), is a comprehensive content management platform solution for
building websites, mobile apps and forms - making it easy to manage your marketing content and assets
AEM is a component of the Adobe Marketing Cloud, which is a suite of solutions that integrate with AEM
such as Adobe Target, Adobe Analytics, Adobe Campaign, Adobe Social, Adobe Primetime, Adobe Media
Optimizer and Adobe Audience Manager. You can use AEM alone, or in conjunction with one or more of
the other components for a complete digital marketing solution.
History of AEM:
CQ5 is a version of Day CQ portfolio developed by a Swiss-based software company Day Software in
2008, followed by Day CQ 3.5, 4.0, 4.1 and 4.2. Adobe Systems renamed Day CQ5 as Adobe CQ5 after
acquiring Day Software in 2010. Following the release of the fifth version of CQ5 i.e., 5.5, Adobe
renamed it as Adobe Experience Manager (AEM) in 2013 with a sixth version AEM 5.6, Latest version is
6.4.
5
Adobe Experience Manager Developer Guide
Reference:
https://helpx.adobe.com/in/experience-manager/aem-previous-versions.html
a. Pre-requisite: Installed Java Platform, Standard Edition JDK - or other supported Java Virtual Machines.
Experience Manager Quick-start file (Standalone JAR or web-application deployment WAR – Without build
in servlet engine / server).
When first installing AEM or CQ, the name of the quickstart jar can be used to determine whether the
instance uses the author run mode or the publish run mode.
cq-<optional-version-or-identifier>-<standard-run-mode>-<port-number>
aem-<optional-version-or-indentifier>-<standard-run-mode>-<port-number>
As an example, the quickstart jar for an AEM 6.0 instance running as an author instance with the port of
4502 could be named:
aem-6.0.0.20140515-author-4502.jar or aem-author-p4502
Reference: https://helpx.adobe.com/experience-manager/kb/RunModeSetUp.html
6
Adobe Experience Manager Developer Guide
Note: As we know Java allocate objects at heap area, sometime it happens we get the ‘Out of memory’
exception, using above command helps in allocating the extra space to heap so that we can avoid
memory exceptions.
Also, we can bind the debug port, it helps in debugging the issues with Java Bundles/Code.
crx-quickstart folder -> bin -> Start.bat (Unix compatible command also can be found)
WEBSERVER - AEM:
Once AEM instance is started, A webserver is also get started at the back end.
Apache Jetty - Internal implementation of AEM comes default. – It’s a servlet engine and HTTP Server.
If needed, different application server can be configured like JBoss/WebLogic – AEM War file is required.
Author:
Author is usually located behind the internal firewall as it is the environment where you and
your colleagues will input your content and administrate the system
Publish:
This environment holds the content you have made available to visitors to
your website; be it public, or within your intranet
7
Adobe Experience Manager Developer Guide
VIEWS IN AEM :
Legacy UI, Extended JS implementation, Not compatible for devices i.e. Unresponsive
Touch -> Coral UI and Granite UI based, responsive and mobile first.
WCM Authoring UI mode Service. (Can change the behavior while opening the page in content or site
admin), Modes (TOUCH & CLASSIC)
8
Adobe Experience Manager Developer Guide
• JCR (Content Repository API for Java): It can be defined as the specifications for accessing content
repository using JAVA API in uniform manner. So, JCR is “type of repository”. CRX is an Adobe
implementation of JCR. Similarly, Apache Jackrabbit is an external implementation of JCR by apache.
Example of traditional Databases – Oracle/SQL Server – Table Concept.
A JCR is an object database that provides various services for storing, accessing, and managing content.
In addition to a hierarchically structured storage, common services of a content repository are versioning,
access control, full-text searching, and event monitoring (JCR Observation Framework - Event Handling
(Modified / Added etc.)
The JCR provides a generic application data store for structured hierarchical data, plus observation,
versioning and full text search.
JCR stores data in form of (Nodes -> Properties (Key/Value)), it forms the hierarchical data model.
• Every File, Folder, Image treats as a node. To differentiate, there is an jcr: primaryType [sling:folder,
nt:folder, etc.]
• Each node will be having jcr: primaryType property and every page would be having a child node
jcr:content, every page will be of type cq: page under content.
• Open JCR node, and see in property console (Protected, Mandatory, Multiple, Auto Created]
• Data is stored in form of TAR (Tape Archive files. (Unix compressed files – Non-readable format)
http://localhost:4502/crx/de
http://localhost:4502/crx/explorer
9
Adobe Experience Manager Developer Guide
Sling:
Apache Sling is a web application framework for content-centric applications, using a Java Content
Repository, such as Apache Jackrabbit or CRX, to store and manage content:
• is used to process HTTP rendering and data-storage requests which assemble, render and send the
content to a client.
• maps Content objects to Components (which render them and process incoming data).
• can be used with a range of scripting languages, including JSP, ESP and Ruby.
OSGI
CQ5 is built within an application framework which is based on the OSGi Service Platform.
OSGI Technology:
• It provides the standardized primitives that allow applications to be constructed from small, reusable
and collaborative components. These components can be composed into an application and deployed.
• OSGi bundles can contain compiled Java code, scripts, content that is to be loaded in the repository,
and configuration or additional files, as needed.
1. Login into CRXDE Lite. In left panel, navigate to the apps folder.
2. Right click on apps folder. Select Create and Create Folder.
10
Adobe Experience Manager Developer Guide
3. Enter the name as training(This will be your project name) and click OK.
Tip:- Always provide node name in lower case, because they become part of the URL.
+
5. Repeat the above process to create a directory structure as follows:
11
Adobe Experience Manager Developer Guide
Label myTemplate
1(ranking indicates the order in which the template appears on the creation
page. Setting rank to 1 ensures that the template appears first in the list.When
Ranking we create a page from site admin)
4. Click the + symbol prided with Allowed Path property. The Allowed Path property defines the
path where this template is to be used to create pages. Add the following value : /content(/.*)?
12
Adobe Experience Manager Developer Guide
Go to Site http://localhost:4502/sites.html/content
On the toolbar-> click Create -> select Create Page.
13
Adobe Experience Manager Developer Guide
14
Adobe Experience Manager Developer Guide
Name Value
Label myComponent
3. Click Next until you reach till last screen. Click OK and click Save All changes.
4. Notice that the myComponent component is created with a default jsp with the same name as
component name myComponent .jsp
5. Double click on myComponent .jsp and replace the jsp code with below code.
1<html>
3<cq:include script="/libs/wcm/core/components/init/init.jsp"/>
5<body>
9</body>
10</html>
15
Adobe Experience Manager Developer Guide
A page is a place where author create and edit content, which will be viewed by site visitors in
publish mode.
In this section we are going to create a basic structure of website and pages in aem.
16
Adobe Experience Manager Developer Guide
5. Enter the title of the page as Home page( This will be our jcr:title ) .
17
Adobe Experience Manager Developer Guide
18
Adobe Experience Manager Developer Guide
Note:- Entering Super Type is not mandatory in case of classic UI, but for opening a page in
touch ui it is mandatory to provide Super Type, JCR internally convert it to
sling:resourceSuperType.
Click Next. Click Finish and Save Changes.
Double click on touchComponent .jsp and replace the jsp code with below code.
1<html>
3<cq:include script="/libs/wcm/core/components/init/init.jsp"/>
4<body>
7</body>
8</html>
19
Adobe Experience Manager Developer Guide
Note: - Make sure that if you are creating a page component. It’s sling:resourceSuperType is set to
/foundation/components/page as It inherits both dialog and cq:dialog. Which will solve both the
editor.html and page properties issues.
Now let’s test our newly created Touch UI component. Follow below steps to test component in
AEM:
Go to Site Admin.
Create a New Folder to maintain readability of Project.
From Top Bar Select New –> New Page.
Enter Page Name
Select Template(Touch UI Template)
Double click on the Page.
By default Page will open in Touch UI if you are using AEM 6 or above.
20
Adobe Experience Manager Developer Guide
Note:- You can always change default authoring environment either to classic UI or Touch UI
If blank/white page is opening in touch ui, make sure that you have added Super Type at the
time of creation of the component or sling:superResourceType is present on component Node.
add sling:superResourceType as parbase if you to inherit attributes from other components.
Like if you want your component to be authorable and draggable add parbase to it.So that they
can inherit the image and text rendering properties when added to a Paragraph system
21
Adobe Experience Manager Developer Guide
Now the next question that arises in our mind by looking at above component is what does
allowedPaths property do or what do we mean by sling:superResourceType.Let’s see
22
Adobe Experience Manager Developer Guide
Change the jcr:title of new component (Like Custom Text Component in above example), so
that we can easily distinguish it.
In CQ WCM , open a page in your web site in authoring mode you can see new component is
available in the side kick under the component group that you have specified.
Approach 2:
Here we will create a custom component with custom dialog, which will have three fields in its
dialog.
Open CRXDE Lite , create a component folder in apps/<myProject>.
Right click on components folder Select Create –> Create Components.
23
Adobe Experience Manager Developer Guide
Click Next till last screen and click OK on last Screen. These screen contains optional
properties which we have already seen above.
24
Adobe Experience Manager Developer Guide
25
Adobe Experience Manager Developer Guide
Click OK and save all changes. You can see that your dialog structure has created.
Provide a suitable name to tab1 value(For Ex: I have provided Custom Link Tab) and save
changes.
Right Click on tab1 or Custom Link Tab and create a node by Selecting Create –> Create Node
of type cq:WidgetCollection.
Enter below details in the Create Node:
Name: Items
Type: cq:WidgetCollection
Note:- name of cq:WidgetCollection should be Items.
Create new node inside the componentItems node which we have just created and enter
below details. Save the changes. your dialog structure would look like below figure.
26
Adobe Experience Manager Developer Guide
Name: displaytext
Type: cq:Widget
Add following properties manually (fieldDescription, fieldLabel, name, xtype) for the
customDisplayText node to configure it as a text field. see below figure for reference.
Similarly create two more nodes on the same level of customDisplayText with
properties shown below:
Name: link
Type: cq:Widget
Name: newWindow
27
Adobe Experience Manager Developer Guide
Type: cq:Widget
Save the changes and your final folder structure should look like:
Open customLinkComponents.jsp and replace the existing code with below code.
1<%@page language="Java"%>
2<%@include file="/libs/foundation/global.jsp"%>
3<cq:include script="/libs/wcm/core/components/init/init.jsp"/>
6<html>
7<head>
8<title>Link Components</title>
9</head>
28
Adobe Experience Manager Developer Guide
10<body>
12</body>
13</html>
Drag the custom link component to page and double click on the link to view the dialog.
29
Adobe Experience Manager Developer Guide
CLIENTLIBS IN AEM:
The AEM Client Library (or ClientLib) functionality will manage all your JavaScript and
CSS resources in your application. It takes cares of dependency management, merging files
and minifying content (removing unnecessary white spaces).
First we make a few components, in this example 3 components are used, we do this all via
CRXDE-lite (http://localhost:4502/crx/de).
Next we are going to add a “clientlib” node of type “cq:ClientLibraryFolder”, inside this
node the JavaScript and CSS resources are stored.
30
Adobe Experience Manager Developer Guide
Add a property to every “clientlib” node called “categories” of type String[] with the single
value of “myproject.components” (to get a String[] type click the “Multi” button).
Now add a Boolean property “allowProxy”, and set this to true. This will make the clientlibs
available via the url /etc.clientlibs/, so it means they are not having the /apps reference.
31
Adobe Experience Manager Developer Guide
first.css
.firstContainer {
margin-top:10px;
first.js
/*
*/
function getNameFirst() {
js.txt
first.js
css.txt
first.css
And repeat the same thing for the other components to achieve something that looks like this:
32
Adobe Experience Manager Developer Guide
Now the setup of the ClientLib is finished we can invoke the ClientLibs in your page compo-
nents. When you are using a JSP you can use cq:includeClientlib . In case you are using the
HTML Template Language (HTL), you can use the data-sly-call to invoke the ClientLib. In
this article HTL will be used for the examples.
We start with putting the following into the <head> element of our page:
33
Adobe Experience Manager Developer Guide
To merge the several clientlib files into one, we define a clientlibs that is embedding the oth-
er categories. Example here is taken from /apps/weretail/clientlibs/clientlib-base.
STEP 5: DEPENDENCIES
Another property you can add to the “clientlib” node is “dependencies”, this way you can
define dependencies between ClientLibs.
Let’s add a dependency on “cq.jquery”:
34
Adobe Experience Manager Developer Guide
To deliver a better performance you can enable “Minify” and “Gzip” for the “Adobe Gran-
ite HTML Library Manager” (previously also called “Day CQ HTML Library Manager”),
in the Felix Configuration console (http://server/system/console/configMgr). These set-
tings are recommended for production installations.
By default the YUI compressor is used when minifying files, you can better use the GCC
(Google Clojure Compiler) for this.
SIGHTLY IN AEM:
Sightly was introduced by AEM 6.0 to replace JSP by a new HTML Templating System.
Below advantages of using Sightly make you to code sightly easier and faster:
35
Adobe Experience Manager Developer Guide
Sightly Offers below advantages over JSP for better development in AEM :
Comments in Sightly:
Sightly Code:
36
Adobe Experience Manager Developer Guide
2 ${properties.jcr:description}
3 </a>
JSP Code:
5 </a>
1 ${properties.myProperty}
1 <span data-sly-test="${isVisible}">${text}</span>
Sightly Use-API
1 <span data-sly-use.obj="script.js">${obj.text}</span>
37
Adobe Experience Manager Developer Guide
1 ${!myVar}
2 ${conditionOne || conditionTwo}
4 ${properties.jcr:title || conditionTwo}
Expression Options
38
Adobe Experience Manager Developer Guide
1 <div
3 format=[currentPage.name,currentPage.title]}">
4 ${concat}
5 </div>
Internationalization in Sightly
1 ${'Page' @ i18n}
39
Adobe Experience Manager Developer Guide
2 <div data-sly-use.nav="navigation.js">${nav.foo}</div>
4 use(function () {
5 return {
7 };
8 });
Output
<div>Hello World</div>
1
Slightly UnWrap Statement: Removes the host element while retaining its content
40
Adobe Experience Manager Developer Guide
2 ${nav.foo}</div>
Output:
Hello World
Slightly Test Statement object: Conditionally removes the element and its content.
1 <span data-sly-test="${properties.showText}">text</span>
Output:
<span>text</span>
1
<span>is true</span>
2
Sightly List Statement: Repeats the content for each enumerable property.
41
Adobe Experience Manager Developer Guide
1 <ol data-sly-list="${currentPage.listChildren}">
2 <li>${item.title}</li>
3 </ol>
Output:
1 <ol>
2 <li>Triangle Page</li>
3 <li>Square Page</li>
4 </ol>
<ol data-sly-list="${currentPage.listChildren}">
1 <li>${item.title} ${currentPage.listChildren.size}</li>
2 </ol>
42
Adobe Experience Manager Developer Guide
Sightly Include Statement: Includes the rendering of the indicated template (Sightly, JSP,
ESP, etc.)
1 <section data-sly-include="path/to/template.html"></section>
Output:
1 <article data-sly-resource="path/to/resource"></article>
Output:
As we have seen above using sightly component development becomes a part of web
developer instead of java developer. It reduces development time and cost for template
designing a lot as you can see in below diagram.
43
Adobe Experience Manager Developer Guide
WCMUsePojo code:
package com.kishore.sightly;
@Override
myMap.put("name", "Kishore");
return myMap;
HTL code:
Name: ${model.myMap['name']}
Many Sling projects want to be able to create model objects – POJOs which are
automatically mapped from Sling objects, typically resources, but also request objects.
Sometimes these POJOs need OSGi services as well.
44
Adobe Experience Manager Developer Guide
In simple terms Sling Models are simple POJO classes which are mapped automatically
with Sling Objects (resource, request objects..) and allow us to access jcr node property
values directly into java classes.
First step during creation of sling model is to adapt the POJO class to a Object type(
Resource, Request etc..)
2 Resource r = getResource();
3 return r.adaptTo(customClassName.class);
45
Adobe Experience Manager Developer Guide
6 @Model(adaptables = Resource.class)
8 ...
9 }
2 @Component
3 @Service
4 @Properties({
7 })
10 @Model(adaptables = Resource.class)
46
Adobe Experience Manager Developer Guide
// Use @Named if jcr node property name is different than class variable.
19
use @Default if you want to assign default values, If empty then assign
20 default value as 'NA'
23 }
26
47
Adobe Experience Manager Developer Guide
// gets executed after the class is created and all variables are injected
@Inject:- email property is always looked from Resource( after adapting to ValueMap),
if this property value is not present then it returns null. If this property is in itself not
available, then it throws exception.
@Inject @Optional: - It is not mandatory to have firstname property in Resource.
@Named: - Use it if jcr node property name is different than class variable.
@Default :- use it if you want to assign default values, If empty then assign default
value as ‘NA’.
@PostConstructor:- annotation defines that this method will run after injecting all
field.
In our last post, we have seen how to create aem multi module project. In this tutorial, i am
going to use the sling model and hello world component that is created by AEM Multi
Module project. You can create sling model in your existing project also. For doing this you
need to check two things.
48
Adobe Experience Manager Developer Guide
1 <dependency>
2 <groupId>org.apache.sling</groupId>
3 <artifactId>org.apache.sling.models.api</artifactId>
4 </dependency>
Note:- You can also verify dependencies from depfinder tool. Search
for org.apache.sling.models.annotations.Model dependency. If it is available then you
are good else add this dependency in pom.
49
Adobe Experience Manager Developer Guide
If you don’t add java packages to your pom.xml then maven won’t add these packages into
header entry of your bundle manifest file. Due to which these classes will not behave as
sling models and will work as simple java classes.
Note: - If you miss to add your sling model package in pom.xml then it won’t through any
error in error.log file.
Go to Crxde.
Go to hello world component (/apps/aemtutorials/components/content/helloworld).
50
Adobe Experience Manager Developer Guide
Below figure will show how we are passing the values from jcr node to sling model and
retrieving it in our hello world component script.
Now lets add one more field in model and retrieve its value in sightly. We have a text
property in dialog box lets add it also to sling model and get it from there to hello
world.html.
51
Adobe Experience Manager Developer Guide
<pre data-sly-
1
use.refObject="org.training.aemcq5tutorials.core.models.HelloWorldModel">
2
${refObject.text}
3
</pre>
52
Adobe Experience Manager Developer Guide
Go to Site Admin.
Create a page Home under english, by using aem content template.
53
Adobe Experience Manager Developer Guide
Right click and edit helloworld component and add text “Welcome to Training” and
click OK.
54
Adobe Experience Manager Developer Guide
The scheduler is a service for scheduling other services/jobs (it uses the open source
Quartz library). The scheduler can be used in two ways, by registering the job through the scheduler API
and by leveraging the whiteboard pattern that is supported by the scheduler. In most cases the
whiteboard pattern is preferred.
Apache Sling Scheduler enables you to easily schedule jobs within your application.
Jobs can be executed at a specific time, regularly at a given period or at the time given by a cron
expression by leveraging the Sling scheduler service.
Scheduling in CQ uses the open source Quartz library, part Sling Commons:
‘org.apache.sling.commons.scheduler.Scheduler’. It is used to execute jobs at predefined
times either periodically or at a set time. It is based on the Quartz scheduling library and can
therefore make use of its syntax for defining the execution times of jobs, making it possible to
precisely indicate times.
The following examples show you how to define and schedule a job by leveraging the whiteboard pattern.
The cron expression format is described in the Quartz Cron Documentation and requires either 6 or 7 fields
separated by white space. The first field always indicates the second (not the minute).
The following job is executed every minute by setting scheduler.expression to the cron expression 0 * * * *
?:
package sling.docu.examples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Property;
55
Adobe Experience Manager Developer Guide
@Component
@Service(value = Runnable.class)
@Property( name = "scheduler.expression", value = "0 * * * * ?")
public class ScheduledCronJob implements Runnable {
/** Default log. */
protected final Logger log =
LoggerFactory.getLogger(this.getClass());
public void run() {
log.info("Executing a cron job (job#1) through the whiteboard
pattern");
}
//
}
The following job is executed every ten seconds by setting scheduler.period to 10:
package sling.docu.examples;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Service;
import org.apache.felix.scr.annotations.Property;
@Component
@Service(value = Runnable.class)
@Property( name = "scheduler.period", longValue = 10)
public class ScheduledPeriodicJob implements Runnable {
/** Default log. */
protected final Logger log =
LoggerFactory.getLogger(this.getClass());
56
Adobe Experience Manager Developer Guide
public void run() {
log.info("Executing a perodic job (job#2) through the
whiteboard pattern");
}
//
}
By default, jobs can be concurrently executed. To prevent this, set the scheduler.concurrent property to
false:
@Property(name="scheduler.concurrent", boolValue=false)
If the same code/same services is executed on multiple nodes within a cluster, the same job might be
scheduled on each instance. If this is not desired, the job can either be bound to the leader of the topology
or a single instance (which one this is, is not further defined):
@Property(name="scheduler.runOn", value="LEADER");
or
@Property(name="scheduler.runOn", value="SINGLE");
Since in contrast to Sling Jobs the scheduler queue is only held in memory, there will be no distribution of
jobs. So if job '1' was scheduled on instance 'a' with the option to run on the leader only, but the leader is
instance 'b', which hasn't the job in the queue, the job will never be executed by any instance!
The scheduler has methods to execute jobs periodically, based on a cron expression or at a given time. For
more details please refer to the javadocs.
The following examples show you how to define and schedule a job that is registered through the scheduler
api.
57
Adobe Experience Manager Developer Guide
The following code sample defines a job object that writes a message in the logs:
To execute the job as defined above at 10:15am every Monday, Tuesday, Wednesday, Thursday and
Friday, you can use the addJob() method with the following parameters:
To execute the job as defined above every 3 minutes (180 seconds), you can use the addPeriodicJob()
method with the following parameters:
To execute the job as defined above at a specific date (on January 10th 2020), you can use the fireJobAt()
method with the following parameters:
58
Adobe Experience Manager Developer Guide
The code implementing a service that simultaneously executes the job based on 3 different kinds of
scheduling can look as follows:
package sling.docu.examples;
import java.io.Serializable;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import org.apache.sling.commons.scheduler.Scheduler;
import org.osgi.service.component.ComponentContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Reference;
/**
* This service executes scheduled jobs
*
*/
@Component
public class HelloWorldScheduledService {
/** Default log. */
protected final Logger log =
LoggerFactory.getLogger(this.getClass());
/** The scheduler for rescheduling jobs. */
@Reference
private Scheduler scheduler;
59
Adobe Experience Manager Developer Guide
60
Adobe Experience Manager Developer Guide
}
//case 3: with fireJobAt(): executes the job at a specific date
(date of deployment + delay of 30 seconds)
String jobName3 = "case3";
final long delay = 30*1000;
final Date fireDate = new Date();
fireDate.setTime(System.currentTimeMillis() + delay);
Map<String, Serializable> config3 = new HashMap<String,
Serializable>();
final Runnable job3 = new Runnable() {
public void run() {
log.info("Executing job3 at date: {} with a delay of:
{} seconds", fireDate, delay/1000);
}
};
try {
this.scheduler.fireJobAt(jobName3, job3, config3,
fireDate);
} catch (Exception e) {
job3.run();
}
}
protected void deactivate(ComponentContext componentContext) {
log.info("Deactivated, goodbye!");
}
}
61
Adobe Experience Manager Developer Guide
Lets write a sling servlet that returns json data by registering using path. When you create a
project using AEM plugin, it will create a sample servlet file for you under core–> servlet
Open SimpleServlet.java file and paste below code, i will explain the code line by line.
1 /*
3 *
5 * you may not use this file except in compliance with the License.
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
13 * See the License for the specific language governing permissions and
62
Adobe Experience Manager Developer Guide
15 */
16 package org.training.aemcq5tutorials.core.servlets;
17
18 import org.apache.felix.scr.annotations.Reference;
19 import org.apache.felix.scr.annotations.sling.SlingServlet;
20 import org.apache.sling.api.SlingHttpServletRequest;
21 import org.apache.sling.api.SlingHttpServletResponse;
22 import org.apache.sling.api.resource.Resource;
23 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
24 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
25 import org.apache.sling.commons.json.JSONException;
26 import org.apache.sling.commons.json.JSONObject;
27
28 import javax.jcr.Repository;
29 import javax.servlet.ServletException;
63
Adobe Experience Manager Developer Guide
30 import java.io.IOException;
31
32 /**
33 * Servlet that writes some sample content into the response. It is mounted
for
34
* all resources of a specific Sling resource type. The
35
* {@link SlingSafeMethodsServlet} shall be used for HTTP methods that are
36
* idempotent. For write operations use the {@link SlingAllMethodsServlet}.
37
*/
38
@SuppressWarnings("serial")
39
@SlingServlet(paths = "/bin/custom/path")
40
public class SimpleServlet extends SlingSafeMethodsServlet {
41
@Reference
42
private Repository repository;
43
@Override
44
protected void doGet(final SlingHttpServletRequest req,
45
64
Adobe Experience Manager Developer Guide
60
}
65
Adobe Experience Manager Developer Guide
AJAX CALL THAT YOU C AN USE TO CALL THIS SERVLET USING R EST API:
$.ajax({
1
type : "POST",
2
url : '/bin/custom/path',
3
/*data : {
4
pass your request parameter here, currently we are not passing any
5
data
6
},*/
7
success : function(data, textStatus, jqXHR) {
8
//write your logic that you need to perform on sucess
9
},
10
error : function(XMLHttpRequest, textStatus, errorThrown) {
11
//write your logic that you need to perform on error
12
}
66
Adobe Experience Manager Developer Guide
13 });
Now go to your browser type http://localhost:4502/bin/custom/path and you can see you
json, This url can be used by front end developers to get the json response and process it
accordingly.
Lets write a sling servlet that returns json data by registering using resource type and
selector.
Again Open SimpleServlet.java file and paste below code, i will explain the code line by
line.
1 /*
3 *
5 * you may not use this file except in compliance with the License.
67
Adobe Experience Manager Developer Guide
7 *
8 *
12 * See the License for the specific language governing permissions and
14 */
15 package org.training.aemcq5tutorials.core.servlets;
16
17 import org.apache.felix.scr.annotations.Reference;
18 import org.apache.felix.scr.annotations.sling.SlingServlet;
19 import org.apache.sling.api.SlingHttpServletRequest;
20 import org.apache.sling.api.SlingHttpServletResponse;
21 import org.apache.sling.api.resource.Resource;
68
Adobe Experience Manager Developer Guide
22 import org.apache.sling.api.servlets.SlingAllMethodsServlet;
23 import org.apache.sling.api.servlets.SlingSafeMethodsServlet;
24 import org.apache.sling.commons.json.JSONException;
25 import org.apache.sling.commons.json.JSONObject;
26
27 import javax.jcr.Repository;
28 import javax.servlet.ServletException;
29 import java.io.IOException;
30
31 /**
32 * Servlet that writes some sample content into the response. It is mounted
for
33
* all resources of a specific Sling resource type. The
34
* {@link SlingSafeMethodsServlet} shall be used for HTTP methods that are
35
* idempotent. For write operations use the {@link SlingAllMethodsServlet}.
36
*/
37
69
Adobe Experience Manager Developer Guide
38 @SuppressWarnings("serial")
39 @SlingServlet(resourceTypes = "geometrixx/components/homepage",
40 selectors = "data",
41 extensions = "html",
42 methods = "GET",
43 metatype =true)
45 @Reference
47 @Override
70
Adobe Experience Manager Developer Guide
54 for(int i=0;i<keys.length;i++){
55 try {
56 jsonobject.put(keys[i], repository.getDescriptor(keys[i]));
57 } catch (JSONException e) {
59 e.printStackTrace();
60 }
61 }
62 resp.getWriter().println(jsonobject.toString());
63
64 }
71
Adobe Experience Manager Developer Guide
AJAX CALL THAT YOU C AN USE TO CALL THIS SERVLET USING R EST API:
$.ajax({
1
type : "POST",
2
url : '/content/geometrixx/en.data.html,
3
/*data : {
4
pass your request parameter here, currently we are not passing any
5
data
6
},*/
7
success : function(data, textStatus, jqXHR) {
8
//write your logic that you need to perform on sucess
9
},
72
Adobe Experience Manager Developer Guide
12 }
13 });
When we register a servlet using path , we must be specific what all paths are allowed
as If we define something randomly, our servlet might not be function properly. Only a
limited set of paths are allowed and the rest are blocked. We can add more path using
Apache Sling Servlet / Script Resolver and Error Handler. Allowing more paths to
execute servlet make you application vulnerable. That’s why you should not open more
doors for servlets to run until and unless it is required.
73
Adobe Experience Manager Developer Guide
You might also need to tell specific paths to your consumers , who are consuming
servlet response using ajax and any change in that path could have a serious affect.
This might not be the case when you use resourceType.
Sling Engine will take care of permissions if you register servlet using Resource Type.
Users who cannot access a particular resource will not be able to invoke the servlet.
DO’S
1 @SlingServlet(
2 resourceTypes = "sling/servlet/default",
3 selectors = "selector",
4 extensions = "tab",
5 methods = HttpConstants.METHOD_GET
6 )
74
Adobe Experience Manager Developer Guide
DONT
@Component
1
@Service(value = javax.servlet.Servlet.class)
2
@Properties({ @Property(name = "sling.servlet.resourceTypes", value = {
3 "sling/servlet/default" }),
DO’S
1 @SlingServlet(
4 )
5 @Properties({
75
Adobe Experience Manager Developer Guide
8 })
DONT
@SlingServlet(methods = "GET")
1
@Properties({
2
8
})
DO’S
76
Adobe Experience Manager Developer Guide
1 @SlingServlet(
4 )
DONT
1 @Service
2 @Component
3 @SlingServlet(
6 )
77
Adobe Experience Manager Developer Guide
An OSGi service is a java object instance, registered into an OSGi framework with a set of properties. Any java
object can be registered as a service, but typically it implements a well-known interface.
The OSGi R3 specification, chapter 4.10 is highly recommended reading. Also, the javadoc for BundleContext
contains lot of information.
The client of a service is always an OSGi bundle, i.e. a piece of java code possible to start via the
BundleActivator interface.
Each bundle may register zero or more services. Each bundle may also use zero or more services. There exists
no limit on the number of services, more than the ones given by memory limits or java security permissions.
Both publishing/registering and usage of services can be restricted by using java security permissions.
Note: a service can also be registered as several interfaces. In this case, the object must implement all of the
interfaces.
An OSGi service factory is a special class ServiceFactory, which can create individual instances of service
objects for different bundles.
Sometimes a service needs to be differently configured depending on which bundle uses the service. For
example, the log service needs to be able to print the logging bundle's id, otherwise the log would be hard to
read.
A service factory is registered in exactly the same way as a normal service, using register Service, the only
difference is an indirection step before the actual service object is handed out.
The client using the service need not, and should not, care if a service is generated by a factory or by a plain
object.
78
Adobe Experience Manager Developer Guide
Note: The framework will cache generated service objects. Thus, at most one service can be generated per
client bundle.
The service concept is a very general-purpose tool, but some examples are:
Generally, services is the preferred method bundles should use to communicate between each other.
Services are always accessed via Service References, which uniquely points to a service object.
To access a service, the following procedure must always be used (possibly wrapped by utility code):
1. Get a ServiceReference
2. Get the service object from the reference, using BundleContext.getService()
All cases, except the first, allow the client to specify a set of properties that the service must fullfill. These
properties are specified using LDAP filters. Zero or more service references can match a given filter.
79
Adobe Experience Manager Developer Guide
A typical filter contains a class name and a set of properties. The example below matches a Http service having
a "port" property equal to 80.
(&(objectclass=org.osgi.service.http.HttpService)(port=80))
As soon as a ServiceReference is available, the service object can be accessed using a cast:
After this, the service object can be accessed as any other java object. Actually, it is a fully normal java object,
more exact, it is the same object as the bundle registering the service created.
RELEASING SERVICES
As soon as the service isn't needed anymore, the client should release the service by calling the
BundleContext.ungetService() method.
bc.ungetService(sr);
All services are automatically released when the client bundles stops. No special service cleanup is needed in
BundleActivator.stop().
Note that service should only be released when really unused. Some services may keep a state for each using
bundle, and releasing the service will release this state, which may, or may not, be the intention. Each service
documentation must be consulted. An example of this is the HttpService, which will remove all servlets and
resources from itself when a client releases the HttpService.
Some special words are needed when using service listeners. A listener will get a
ServiceEvent.UNREGISTERING event when a service is in the process of being unregistering from the
framework.
While in this UNREGISTERING listener, the getService() call should not be expected to return a valid
service object. In fact, the expected value is null, even if the spec is a bit vague on this. The OSGi reference
implementation does however return null in this case.
Note: It's fully possible for a client to hold on to a service object via a variable, even after the exporting
bundle has been stopped. The client shouldn't expect the service to work in this case and this also blocks any
garbage collection. Thus, don't forget to null variables holding services when the service is released.
OSGi services must always be considered volatile, and may disappear or become unusable at any time.
Suggested practices:
80
Adobe Experience Manager Developer Guide
01: ServiceReference sr =
bc.getServiceReference(HttpService.class.getName());
02: HttpService http = (HttpService)bc.getService(sr);
03: http.registerServlet(....)
Three things can fail, one for each line!
Additionally, the code above does not handle the case where more than one service is registered and actions
should be taken on each of them.
01: ServiceReference sr =
bc.getServiceReference(HttpService.class.getName());
02: if(sr != null) {
03: HttpService http = (HttpService)bc.getService(sr);
04: if(http != null) {
05: http.registerServlet(....)
06: }
07: }
This approach quickly becomes very cumbersome, and also creates an undesirable start order problem, since
the HttpService must be available when the code is run.
By using a service listener, the code can avoid the first ServiceReference null problem:
81
Adobe Experience Manager Developer Guide
The possible Runtime Exception when actually calling the service (line 8) is handled by the framework event
delivery code, so if no special handling is needed in the client code, nothing needs to be done.
There's still one problem -- if all HttpServices already had been registered, the listener above would not be
called until the HttpServices were restarted. A small trick solves this: Manually construct REGISTERED Service
Events and call the listener:
18: try {
19: bc.addServiceListener(sl, filter);
20: ServiceReference[] srl = bc.getServiceReferences(null, filter);
21: for(int i = 0; srl != null && i < srl.length; i++) {
22: sl.serviceChanged(new ServiceEvent(ServiceEvent.REGISTRED,
23: srl[i]));
24: }
25: } catch (InvalidSyntaxException e) {
26: e.printStackTrace();
27: }
Now the number of lines has grown from three to 25+. Which may be OK if this is a one-time operation. But if
continuous use of a service is intended, it's easier to use a ServiceTracker:
ServiceTracker example
82
Adobe Experience Manager Developer Guide
03: ((LogService)logTracker.getService()).doLog(...);
The tracker guarantees to hold all currently available services, but may naturally return null if no services are
available. This is often OK, since the code need to be prepared for RuntimeException anyway.
The down-side of this approach is the continuous and annoying usage of casting to get the desired object.
Wrapping this in a single utility method can ease usage a bit:
Consider the HttpService case. All clients must constantly monitor the framework in some way to add its
servlet(s) to the web server. This requires at least the amount of code examplified above, and even this
doesn't completely guard against timing problems.
Additionally, the Http service must provide special methods for adding and removing servlets, and maintain an
internal list of added servlets. This adds complexity both to the API and to the internal server code.
This is a very common scenario -- some kind of callbacks/listeners are needed and the server needs to keep
track of all available listeners.
Thus, an alternative and better approach is to let the client register its servlets into the framework, and
let the http server use this list instead.
Servlet client
83
Adobe Experience Manager Developer Guide
The client needn't do anything more. If the servlet should be removed, it is simply unregistered from the
framework.
10: reg.unregister();
The new, improved http server would monitor the framework for all services being HttpServlets, and use the
"alias" property to set the alias.
Below is a minimalistic wrapper for the existing http service: (a complete class doing this can be found in the
Http Console example code.
HttpService wrapper
void open() {
httpTracker = new ServiceTracker(bc, HttpService.class.getName(), null);
httpTracker.open();
84
Adobe Experience Manager Developer Guide
85
Adobe Experience Manager Developer Guide
WORKFLOWS IN AEM
Workflow is a well-defined series of steps that allows to automate activities of Experience Manager. It is
divided into various steps including people (participants), procedures (process) or some tools. The flow of
workflow can be either sequential or parallel when multiple procedures can run parallely to each other. In
short, a workflow is similar to a flow-chart which describes the series of procedures to be executed having
multiple participants to achieve a desired outcome.
There are many out of the box workflow models available for use and we can write our custom workflows
which can be tailored as per the business needs of the company.
There can be plethora of use cases for writing workflows that may depend on the business needs.
For example, the process of publishing a page can be customized and tailored for inclusion of some special
participants that need to approve the request for activation or send a mail after approval or rejection.
WORKFLOW MODELS
Workflow Model is a container or blueprint of the workflow that combines the workflow steps and link them
logically.
It has a start and an end node (plus an optional participant step) by default.
It can contain different nodes and the transitions that link them. The workflow nodes can get any input from
author or can do processing via Java code or ECMA scripts.
Workflow payload is an important term which is considered as a resource on which workflow will perform
its functions.
List of workflows can be seen on http://localhost:4502/libs/cq/workflow/content/console.html.
86
Adobe Experience Manager Developer Guide
87
Adobe Experience Manager Developer Guide
Thereafter, we can edit the workflow created to customize it. This is the by default view of the workflow wherein
there is a start and an end node with a default participant step.
88
Adobe Experience Manager Developer Guide
WORKFLOW NODES
There are many workflow nodes that can be dragged and dropped such as Participant step, process step, and split, or
split, dialog participant step, form participant step, container step, go to step etc.
1. PARTICIPANT STEP: In this step the user can give
Title and description and select a user or a group.
The email option will send an email in the inbox of the user/group.
89
Adobe Experience Manager Developer Guide
90
Adobe Experience Manager Developer Guide
Now, to add our own process in the list we have to make a workflow process and register it as a service in java and
can add the logical code that will execute on this process step
@Service(WorkflowProcess.class)
@Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap args) throws WorkflowException
{
}
This code snippet shows the basic skeleton of a workflow process that it required for process step.
@Component will register our Java class as a component with the properties that enables it immediately and helps
it get the metadata provided by the execute method of WorkflowProcess class.
@Service will register our Java class as a service to be used in the Workflow process.
@Properties will add certain properties such as process.label which will show our class in the process list of the
process step. The value of this property will be shown in the drop down list.
The Java class should implement WorkflowProcess interface and give definition to execute method. This method
provides three arguments namely WorkItem, WorkflowSession, MetaDataMap.
WorkItem defines the currently started java process. It contains the data of the workflow and can be fetched
using this argument such as Id, workflow, workflow data etc. We can access the workflow object using this. We
can get payload of the data using a method of workItem.
WorkflowSession controls the workflow by providing methods that can deploy, complete, create, start,
stop, resume, suspend, retrieve, complete workflow models, instances or user/groups. We can start another
workflow using workflow session of current workflow.
MetadataMap is a Map<String, Object> of properties that are entered in the dialog of the process step. We
can fetch the list of the arguments from metadata map.
There can be many other types of steps that can be configured within the workflow and can be tailored using java
code, scripts, parameters etc. to provide the desired functionality.
91
Adobe Experience Manager Developer Guide
3. An OR SPLIT can be used to introduce branching in the workflow with which only one branch of the
workflow can be activated (conditional) based on the script which is mentioned in the dialog.
The user can give either the path of the script or can write ECMA script in the given tab.
The Common tab has an option to select the number of branches required in the OR Split.
92
Adobe Experience Manager Developer Guide
Figure 10: ECMA script written for branch 1 (set as default route).
We can write different condition for branch 2 or can upload a script.
4. AND SPLIT wherein all the branches go parallely and we can execute tasks for multiple processing.
5. A CONTAINER STEP can allow another workflow to be executed as a child of the current workflow.
This workflow is a sub workflow that can be instantiated. Another way of performing the same action is via
Java code where we can start a workflow using workflowSession.
workflowSession.startWorkflow(workflowModel, workflowData);
This code snippet gets the model of the child workflow that needs to be invoked. Thereafter, the data of the
workflow is created which is used to start the workflow in the current session.
6. GOTO STEP traverses between the steps in the workflow based on the result of the ECMA script. It can be
used to implement the use case of looping in the workflow process.
7. DIALOG PARTICIPANT STEP is a special scenario of participant step where the user/group needs to give
some information that is to be used in the workflow.
1. The additional step in this step is to provide a path of the dialog. We have to make that dialog in
CRX (/etc/workflows/dialog) and provide the path of that dialog to receive the input from the selected
user/group.
2. The structure of the dialog should be cq:dialog type. This data can be stored in the form of payload
(when we set the value of the property as ./jcr:content/nodename) which can be overwritten in
subsequent uses of this dialog.
3. The data can also be stored with the work item (when the value is node name) metadata and is
persisted with subsequent use of dialog.
WORKFLOW LAUNCHERS:
Workflow launchers can be used to trigger the workflow based on some event that can be specified in the
launcher. We can add a launcher under the Launcher tab.
93
Adobe Experience Manager Developer Guide
94
Adobe Experience Manager Developer Guide
Have you ever wondered how to easily create text snippets in Adobe Experience
Manager (AEM) and store them in the AEM repository, for easy re-use when authoring
web pages, mobile applications, social content, and so on?
In AEM 6.2, you can use content fragments that let you create original content in AEM,
enabling copy writers to create editorial content before it is being authored in a page,
and to further allow curating such content by creating channel specific variations and by
associating collections with relevant media content. As a result, web producers receive
content that is prepared and "ready to go”, enabling them to focus on assembling
content across channels, globally and on a local level.
95
Adobe Experience Manager Developer Guide
Content Fragments
Content Fragments are based on templates; not page templates, but specific fragment
templates.
Fragment templates are created and maintained in the AEM repository by using CRXDE
Lite. Typically, copy writers and authors select a template when creating a content
fragment.
Elements
Self-contained pieces of editorial content that are meant to be authored in a page with
their own design and layout, i.e. component, as opposed to "paragraphs" which are
meant to be authored with a common component.
Default content
96
Adobe Experience Manager Developer Guide
Fragments themselves have a name/title value, like every AEM asset, and contain the
following structural elements:
Paragraphs
Variations
Copies of the content master that are optimized for a certain editorial purpose or
channel. A mobile variation can for example be optimized for a mobile channel, by
removing and/or rewriting certain parts of a master. Or an email variation can be
optimized for using the same content in emails.
Associated Collections
Relevant media content that is added to the fragment. Purpose is to expose channel
producers to only this curated media content during production rather than the entire
repository.
Content Fragments do not contain any layout and design beyond rich text formats.
Fragments are pure content. Experiences are created by combing fragments with AEM
components when authoring them in a page or other channel (mobile, email, etc.).
Components add layout and design.
Note:
Cycling is Awesome
Cycling is essentially the perfect outdoor activity. With limitless bike options and
seemingly endless trail choices, cycling accommodates all fitness levels and age
groups, Chose your own adventure.
97
Adobe Experience Manager Developer Guide
This fragment uses a "Simple" template provided with AEM. This template provides for
a single element,
named Main.
4. Click the Create and select Content Fragment from the drop-down menu.
Create Fragments
5. In the New Content Fragment wizard, select the Simple Fragment template and
click the Next.
6. Specify biking as the title and editorial content about riding bicycles as the
description.
98
Adobe Experience Manager Developer Guide
7. Click on the Tag icon to open the Tag Selector and select Geometrixx-Outdoors >
Activity > Biking.
11. Paste the biking text that is specified at the start of this article.
You can edit text defined in content fragments. For example, you can define headings.
To edit text defined in content fragments, perform these steps:
99
Adobe Experience Manager Developer Guide
4. Click on the Paragraph icon to open the paragraph style drop-down list and select
Heading 3.
CREATE A VARIATION
You can create a channel-specific variation of this fragment for use in different AEM applications. In this example, a
mobile variation is created, as shown in the following illustration.
100
Adobe Experience Manager Developer Guide
Mobile variations
1. Click on the Variations link (in the left pane) and click Create Variation.
101
Adobe Experience Manager Developer Guide
2. In the New Variation dialog, specify the mobile as the title and shortened content
for the mobile channel as the description.
3. Add the sentence This is mobile to the text to the end of the text.
You can link an Asset Collection to a content fragment by performing these steps:
1. Click the Edit link in the top corner to open the drop-down list.
Associated Content
102
Adobe Experience Manager Developer Guide
Collection Selector
Note:
If you do not see an Asset Collection, create a new one. For details, see Managing Collections.
4. Click on the arctic collection to select it and click the checkmark icon to associate the
collection with this fragment. You will now see the assets associated with this fragment.
103
Adobe Experience Manager Developer Guide
5. Finally, click the checkmark in the top right corner to save the Content Fragment. This
takes you back to the Assets Admin.
104
Adobe Experience Manager Developer Guide
2. Click on the Tag icon to open the Tag Selector and select Geometrixx-Outdoors
> Season > Summer.
4. Click the checkmark in the top right corner to save the Content Fragment.
You can add a content fragment to an AEM web page by performing these tasks:
105
Adobe Experience Manager Developer Guide
In this section, you can use the AEM Sites Page Editor to add the Content
Fragment into a web page.
1. To start, switch to the Page Editor browser tab for the Biking web page at:
http://localhost:4502/editor.html/content/geometrixx-
outdoors/en/activities/cajamara-biking.html
Biking Page
106
Adobe Experience Manager Developer Guide
Note:
If the side panel on the left side of the screen is not visible, click the Toggle Side Panel button
(furthest to the left) in the top toolbar.
You can add a Content Fragment in an AEM web page by performing these steps:
1. From the components section under the General category, select Content Fragments
and drag and drop this component onto the page.
2. In the side panel, switch to the Asset Finder (if it is not displayed). In the type
selector, select Content Fragments, as shown in this illustration.
107
Adobe Experience Manager Developer Guide
Content Fragments
108
Adobe Experience Manager Developer Guide
4. Drag the biking Content Fragment into the Content Fragment drop area (that you
dropped in step 1) in the page. Click on the first header to reveal the component’s
toolbar.
6. Select the Range radio button and enter 1 as the paragraph range.
You can add additional assets to a content fragment, which is known as an associated
asset. Perform these steps:
109
Adobe Experience Manager Developer Guide
2. Drag and drop the Image - Sightly component above the header Cycling is
Awesome.
110
Adobe Experience Manager Developer Guide
3. In the side panel, switch to the Associated Assets list. Drag and drop the an image
into the Image component.
Dragging an image
111
Adobe Experience Manager Developer Guide
An Experience Fragment is a group of one or more components including content and layout
that can be referenced within pages. They can contain any component.
An Experience Fragment:
If an author wants to re-use parts (a fragment of an experience) of a page, they need to copy and
paste that fragment. Creating and maintaining these copy/paste experiences is time-consuming
and prone to user errors. Experience Fragments eliminate the need for copy/paste.
To support the headless CMS use-case. Authors want to use AEM only for authoring but not for
delivering to the customer. A third party system/touchpoint would consume that experience and
then deliver to the end user.
Note:
Write access for experience fragments requires the user account to be registered in the group:
experience-fragments-editors
Please contact your system administrator if you are experiencing any issues.
112
Adobe Experience Manager Developer Guide
o Experiences that make sense to group (for example a campaign with different experiences
across channels)
When you use Omnichannel Commerce.
o Sharing commerce-related content on social media channels at scale
o Making touchpoints transactional
Creating folders allows you to create a meaningful structure for your Experience
Fragments.
113
Adobe Experience Manager Developer Guide
3. From the required folder, select Create then Experience Fragment to open the Create
Experience Fragment wizard.
Note:
You can use the template editor to create your own template.
114
Adobe Experience Manager Developer Guide
Only editable templates can be used; static templates are not fully compatible.
A Title is mandatory. If the Name is left blank it will be derived from the Title.
5. Click Create.
The Experience Fragment Editor offers you similar capabilities to the normal page Editor. See
Editing Page Content for more information on how to use it.
The following example procedure illustrates how to create a teaser for a product:
115
Adobe Experience Manager Developer Guide
You can create variations of your Experience Fragment, depending on your needs:
116
Adobe Experience Manager Developer Guide
5. Confirm with Done (tick icon), the new variation will be shown in the panel:
117
Adobe Experience Manager Developer Guide
You can now use your Experience Fragment when authoring your pages:
118
Adobe Experience Manager Developer Guide
119
Adobe Experience Manager Developer Guide
Note:
Edit, in the component toolbar, operates as a shortcut to open the fragment in the
fragment editor.
BUILDING BLOCKS
You can select one or more components to create a building block for recycling within your
fragment:
1. In the Experience Fragment editor, select the components you want to re-use:
120
Adobe Experience Manager Developer Guide
For example:
3. Enter the name of the Building Block, and confirm with Convert:
121
Adobe Experience Manager Developer Guide
4. The Building Block will be shown in the tab, and can be selected in the paragraph
system:
Your building block is visible in the Building Blocks tab. For each block, the following actions
are available:
122
Adobe Experience Manager Developer Guide
You can drag your building block to the paragraph system of any fragment, as with any
component.
Using the .plain. selector in the URL, you can access the plain HTML rendition.
This is available from the browser, but its primary purpose is to allow other applications (for
example, third party web apps, custom mobile implementations) to access the content of the
Experience Fragment directly, using only the URL.
The plain HTML rendition adds the protocol, host and context path to paths that are:
For example:
.../brooklyn-coat/master.plain.html
Note:
Links always reference the publish instance. They are intended to be consumed by third parties,
so the link will always be called from the publish instance, not the author.
123
Adobe Experience Manager Developer Guide
124