ADOBE EXPERIENCE MANAGER (AEM)
AEM JavaScript Use-API
Tips and resources for using AEM’s Sightly / HTL JavaScript Use-API for writing server-side JavaScript. The AEM JavaScript Use-API ResourceUtils page contains examples for using ResourceUtils and functions.
About
AEM uses Rhino to compile server-side JavaScript into Java. All of the regular Java libraries are available by using the class path in the server-side JavaScript. Since the server-side JavaScript is slower than using Java, it’s best to use when the components will be cached in the dispatcher.
Example
Navigate to the equipment page in author mode, e.g., /editor.html/content/we-retail/us/en/equipment.html
. Scroll down to the Featured Products panel. Notice the descriptions below the product names are all lowercase. e.g., footwear, helmet, shirt …
Let’s create a server-side JavaScript file to title case these descriptions.
In crx/de
, e.g., http://localhost:4502/crx/de, expand /apps/weretail/components/content/productgrid
.
Right-click item
and select Create > Create File
Name the file item.js
and add the following JavaScript Use-API code:
"use strict";
use( function() {
var data = {};
/**
* `this.item` is the item parameter object
* passed from the HTL template
*/
data.description = toTitleCase(this.item.description);
function toTitleCase(str) {
var _str = new String(str);
return _str.replace(/(^|\s)[a-z]/g, function(chr){ return chr.toUpperCase() });
}
return data;
});
Edit /apps/weretail/components/content/productgrid/item/item.html
adding a sly
element to use the server-side JavaScript file and pass it the item
data. e.g.,
After
<li class="foundation-list-item"
data-sly-use.item="we.retail.core.model.ProductGridItem"
data-sly-test="${item.exists}">
Add
<sly data-sly-use.product="${'item.js' @ item=item}" />
Replace
${item.description}
With
${product.description}
Reload the /editor.html/content/we-retail/us/en/equipment.html
page in author mode and the descriptions should now be title cased.
Component Properties
To access the properties of a page or component, refer to the following examples.
Using POJO
var pageTitle = currentPage.properties["jcr:title"];
// all three of these component property examples work
var txtTest1 = granite.resource.properties["text"];
var txtTest2 = resource.properties["text"];
var txtTest3 = properties["text"];
Using the properties
JcrPropertyMap
var pageTitle = currentPage.properties.get("jcr:title");
If you want to specify a value to use when the property does not exist, you can after the property name. e.g.,
var title = properties.get("myproperty", '');
Parameters
As we saw in the example above with <sly data-sly-use.product="${'item.js' @ item=item}" />
, objects that are not properties of the respective component can be passed to the Use-API using parameters. The next part contains another example of this.
Java Classes
Java classes can be accessed directly with the classpath. e.g.,
var beer = "lager";
var wine = "pinot grigio";
var difference = org.apache.commons.lang.StringUtils.difference(beer, wine);
Type Casting
Using native JavaScript methods, e.g., toLowerCase()
on objects that do not originate within the script need to be cast. For example, cast the java.lang.String
to new String();
e.g.,
var name = new String(this.data.name);
Debugging / Logging
Debugging is essential to development, especially when trying to learn what JavaScript patterns, variables, etc. can be utilized within the Use-API. Unfortunately, debugging with breakpoints, etc. is not supported and we’re relegated to using logs and output strings.
Custom Log File
Navigate to the Web Console and select Sling: Log Support. e.g., http://localhost:4502/system/console/slinglog
-
Select Add new Logger,
-
Select DEBUG for the log level, e.g., Log Level: DEBUG;
-
Enter a log file path, e.g., Log File:
logs/debug.log
-
Enter a path for the Logger, e.g.,
apps
-
Select the Save button
Create a server-side JavaScript file to test the logger.
In crx/de
, e.g., http://localhost:4502/crx/de
expand apps/weretail/components/structure
right-click page
and select Create > Create File
name the file, e.g., example.js
and add the following Use-API code:
"use strict";
use( function() {
log.debug('### TESTING');
});
Edit /apps/weretail/components/structure/page/body.html
and add a sly
element to use the server-side JavaScript file. e.g.,
<div class="container">
...
<sly data-sly-use.test="${'example.js'}"></sly>
</div>
Load the URL to test the file, for example, http://localhost:4502/content/we-retail/us/en.html
Read the log file
This example shows how to tail the log in a terminal session. Use tail
to monitor log files in real time. The -n300
argument show the last 300 lines. The default is only 10 lines.
cd /opt/aem/author/crx-quickstart/logs
tail -n300 -f debug.log
Use the tail command with the
-f
argument to follow the content of a file. Use the-F
argument to follow the creation of a new log.
This example shows how to return only log entries for a specific Use-API class.
tail -f debug.log | grep {Use Class name}
If you want to use the a web browser to view the log file, open the WebTail endpoint to read the last 1000 lines of the custom log file, for example:
http://localhost:4502/system/console/slinglog/tailer.txt?tail=1000&name=%2Flogs%2Fdebug.log
Resources
Part 1 of 4 in the AEM JavaScript Use-API series.