Adobe Experience Manager | AEM/CQ | Apache Sling

Use custom Granite render conditions to determine if Touch UI components should display in AEM.
Granite render conditions can be used to determine whether a component should be rendered or not. From the Render Condition documentation, a "typical example would be to render a submit button based on whether the current user has a privilege to create or modify a resource." Render conditions can be used to help guide the author by dynamically customizing forms based on known information.

Download the sample project on GitHub at https://github.com/nateyolles/aem-granite-rendercondition-demo which includes various examples of utilizing the built-in render conditions as well as examples on how to create your own custom render conditions, how to pass in data to those render conditions and how to evaluate Expression Language with your custom render conditions.

Screenshot of an AEM admin form using Granite render conditions
There are many examples of render conditions throughout AEM and an easy way to start exploring is to query for the most basic render conditions from within CRXDE Lite using something like  /jcr:root//*[@sling:resourceType='granite/ui/components/foundation/renderconditions/simple']. You can find the standard render conditions such as  simpleandornot and  privilege under  /libs/granite/ui/components/foundation/renderconditions. There are a few custom render conditions under  /libs/cq/gui/components/projects/admin/renderconditions which you can explore, as well as  /libs/cq/gui/components/renderconditions/islocked/libs/wcm/msm/components/touch-ui/renderconditions/isblueprint and  /libs/wcm/msm/components/touch-ui/renderconditions/islivecopy. There is another great example of a custom render condition in the  ACS AEM Commons project which displays components based on the current path.

To utilize this server-side display logic, simply create a node under your Granite widget named granite:rendercondition, set the sling:resourceType to the render condition component such as granite/ui/components/foundation/renderconditions/simple and populate the required properties such as expression. For example, the following textfield will only render when the query string parameter biz equals baz.



Granite render conditions take advantage of JSP Expression Language or EL for short. As such, you have access to param, paramValues, header, headerValues, cookie, requestPathInfo, state and tenant. You also have access to a powerful, yet simple and straight-forward syntax to evaluate logic in Expression Language. Furthermore, Granite provides extra convenience with a few provided EL Functions. For example:



See the Granite UI Documentation on Expression Language for more information regarding available variables and functions. Note that EL expressions can be used outside of render conditions as well. For example, you'll find them granite/ui/components/foundation/hyperlink components to pass data forward, such as:



The simple render conditions are quick and readily available for most basic expressions. However, if you need custom logic, you can write your own render condition. A render condition is simply a JSP component. Within your custom logic you will get the granite:rendercondition resource, retrieve its relevant properties via the resource's Config and set a true or false  SimpleRenderCondition as a request attribute. To evaluate EL expressions, use the ExpressionHelper by way of the ExpressionResolver service, which is powered by the Apache Commons EL interpreter. The combination of a custom render condition and EL expressions is very powerful.



The custom render condition is used the same way the default render conditions are utilized, simply update the sling:resourceType to the path of your custom render condition component and populate your defined resource properties.



When you download the sample project at https://github.com/nateyolles/aem-granite-rendercondition-demo, you'll notice that the most straight-forward condition is the simple render condition and that you can combine conditions by nesting and, or and not conditions. This snippet from the demo project reveals a variety of ways to dynamically render Touch UI components including cookies, headers, query string parameters, selectors, suffixes, JCR privileges and custom render conditions.



You'll notice in the provided sample project that I created a custom Touch UI admin page to help demonstrate the various ways of using the Expression Language to interact with the URL. (If you're interested in how to do that, see Chris Millar's post on How to create an AEM 6.2 Admin Console for Touch UI.) Take note that render conditions work with any Granite widget, however, in specific scenarios, certain challenges exist when trying to use render conditions with component dialogs in your typical Touch UI editing of pages. Remember that an AJAX call is made to open the dialog and the EL expressions are evaluated on that AJAX request, not the request for the page which is in fact /editor.html. Therefore, the path, suffix, selectors and query string parameters are independent of what you see in your browser's address bar when using a normal component dialog in the editor.
Create custom HTML output for AEM clientlibs and Sightly to take advantage of HTML5 and enhance site performance.
AEM clientlibs are extremely powerful. They allow you to produce client-side JavaScript and CSS libraries while controlling minification, concatenation, and dependency management. However, out-of-the-box, they don't allow you to customize the HTML output. While optimizing your website for speed, you may want to use the defer, async, and/or onload attributes on your script elements. Likewise, while managing your cross-origin resource sharing (CORS) HTTP requests, you may want to utilize the crossorigin attribute on your script and/or link elements for JavaScript and CSS.


Using clientlibs in AEM with Sightly is demonstrated in the AEM documentation Using Client-Side Libraries, as well as Feike Visser's ( @heervisscher) Sightly intro part 5: FAQ.



When we follow the data-sly-use block's expression value in our AEM instance, we find three files that work together with the HtmlLibraryManager to provide the final clientlib output. clientlib.html contains named Sightly template blocks ( js, css, all), which in turn set the proper Sightly expression option for mode and call the named Sightly templates in graniteClientLib.html. graniteClientLib.html then sets the proper Sightly expression options and delegates the more complex logic to a Java-Use API POJO. ClientLibUseObject.java then utilizes the HtmlLibraryManager in order to write out the final HTML markup.

All files associated with Sightly clientlibs are viewable in your AEM instance under the /libs/granite/sightly/templates node. To make any alterations, we simply copy all three files out of /libs into /apps, update the files, and update our Sightly components to point to the new clientlib component (usually headlibs.html or similar partial in the page component).



In our case, we want to alter the HTML markup by adding additional attributes to the script and link elements. In order to do that, we first add additional Sightly expression options to all the Sightly templates. In this example, I'm using loading, onload, and crossorigin options.



Once the new Sightly expression options are set, the Java-Use POJO is updated to obtain those options from the provided bindings. AEM hands the responsibility of printing the final HTML markup to the HtmlLibraryManager's writeIncludes, writeCssInclude and writeJsInclude methods. However, since we want custom markup, we need to do that ourselves in the POJO.



I've written a demonstration AEM project as well provided the code which can easily be installed into a single folder for use in your project. There is also an AEM package available for easy install. View the AEM Clientlib Async project on GitHub.
Use com.adobe.granite.confmgr.ConfMgr in AEM to set multi-tenant, ACL protected, inheritance supplied configurations.
As of AEM 6.1 you may have noticed the new /conf node at the root level along with /content, /etc, /apps and /libs. Over time the /etc folder's responsibility has expanded and configurations have been moved in an effort to clean it up a little. Whereas prior to 6.1 you would have stored site configurations in /etc, it's now recommended that you store those configurations under /conf. Along with the new node structure Adobe has provided a valuable, yet simple, utility to help manage these new site configurations in com.adobe.granite.confmgr.ConfMgr and com.adobe.granite.confmgr.Conf.

Read the Adobe provided documentation for  Conf and ConfMgr.

I have created a demo project and hosted it on GitHub at https://github.com/nateyolles/aem-slash-conf.

As an example, let's host a multi-tenant AEM instance with three projects and one subproject: Aviato, Pied Piper, Hooli and subproject Hooli XYZ.

/content/aviato
/content/piedpiper
/content/hooli
/content/hooli/hoolixyz

Add a cq:conf property of type String at the root of every project page and point it to the site's corresponding configuration path. A global configuration will be used if a cq:conf property is not specified as is the case for Aviato in this example.

/content/piedpiper/jcr:content/@cq:conf = "/conf/tentants/piedpiper"
/content/hooli/jcr:content/@cq:conf = "/conf/tentants/hooli"
/content/hooli/hoolixyz/jcr:content/@cq:conf = "/conf/tentants/hooli/hoolixyz"

Conf respects relative paths as it pertains to the cq:conf property. Therefore, the following settings could also be used:

/content/hooli/jcr:content/@cq:conf = "/conf/tentants/hooli"
/content/hooli/hoolixyz/jcr:content/@cq:conf = "hoolixyz"

The tree structure of /conf should closely resemble /content. The configuration nodes should be of type cq:Page with the configuration properties on the jcr:content sub-nodes. All configurations start below the path specified in cq:conf with the addition of /settings.

/conf/global/settings/socialmedia/facebook/jcr:content/@enabled = false
/conf/tenants/piedpiper/settings/socialmedia/facebook/jcr:content/@enabled = true
/conf/tenants/hooli/settings/socialmedia/facebook/jcr:content/@enabled = true
/conf/tenants/hooli/hoolixyz/settings/socialmedia/facebook/jcr:content/@enabled = true

/conf/global is special as it provides an ultimate fallback in the Conf inheritance mechanism. It this example Aviato does not have its own config, so it would use the global configs. /conf/tenants is not dictated by AEM, but is a convention worth following to help prevent namespace collision in multi-tenant scenarios.

Configs can live under /conf, /apps and /libs with the same apps-then-libs type resolution that you are already familiar with. The resolution order can be set in the Felix console com.adobe.granite.confmgr.impl.ConfMgrImpl configuration: http://localhost:4502/system/console/configMgr/com.adobe.granite.confmgr.impl.ConfMgrImpl.

Use a Conf object to get a site configuration. The Conf object is usually obtained by adapted a Resource or Page using Apache Sling's adaptTo() method. Once you have the site's Conf object, you can get any number of predefined ValueMaps and properties. Notice that the ValueMaps cannot be modified – they are read-only. Properties are retrieved from the ValueMap in the familiar way of passing in either a default value or the class type.

The Conf object you retrieve is based on the path of the resource. So if have a Sling Model or WCMUsePojo and you adapt the current page, you will get a different Conf than if you adapt the current resource.



As you can see, the ConfMgr is a fairly lightweight and transparent helper. Everything is in the JCR, so configurations can be accessed through normal channels such as a Resource Resolver. However, there are three main benefits to using com.adobe.granite.confmgr.Conf.

The most obvious advantage is the built in inheritance management. For instance, the site for Hooli might have ten configurations. If the subproject Hooli XYZ overwrites only one of those configurations, it will use the other nine provided by Hooli. If the Conf object is looking for a config that doesn't exist in the subproject or project, it will look under /global. Conf inherits and overwrites at the node level, not the property level.

Conf handles null values for you. If the configuration, ValueMap or individual properties are null, you can continue without null checks and you won't get a Null Pointer Exception.

Conf respects ACLs and multi-tenant privacy. If you setup your ACLs correctly, a shared component between two tenants will still only be able to access the configurations of the current tenant. Conf does not allow relative paths that try to move up the tree and into another tenant (i.e. "../../differentSite/foo/bar").

ConMgr can be used as a service.



When used as a service, a Resource Resolver can be passed in which allows the use of Sling Service Accounts, thereby respecting ACLs on the configurations.



All inherited configurations can be obtained by using the Conf#getList() method, which returns a List of ValueMaps. Configurations can also be chosen explicitly by using a Resource Resolver to get the specific resource.



View a complete example at https://github.com/nateyolles/aem-slash-conf.

Thanks to Alex Klimetschek ( @alexkli) for sharing his knowledge of /conf of which much of this blog post is based on.
Custom validation in AEM Touch UI dialogs
Adobe Experience Manager's Touch UI provides a straightforward validation framework making it simple to create custom form element validators as well as to interface with them programmatically. This blog post details the inner workings of the AEM Touch UI Validation Library which provided unobtrusive validation and enhanced functionality to AEM's Granite UI foundation dialog components.

Custom Multifield validation in AEM's Touch UI dialog.

Registering custom validators is done by calling the jQuery based $.validator.register method. The register method takes a single JavaScript object literal argument. The parameter looks for four properties: selector, validate, show and clear, of which only selector is required.

The following example creates a custom validator for phone numbers in a Touch UI dialog. Note that show and clear methods are not necessary in this example as the validator would use the default AEM provided methods, however, they are included for reference.



The  selector property ties the validator to the form elements on the page. The property accepts any jQuery selector such as a class ( .my-class-name), type ( INPUT) or attribute ( INPUT[type="text"]) selectors.

The  validate property is the function that validates the form element's input. The function provides the form element as a jQuery object as the single available parameter. The field is treated as invalid if this function returns a string literal as the validation error message.

The  show and  clear properties are functions that update the UI when when the form element is determined to be invalid or valid respectively. Each function makes two parameters available, the form element as a jQuery object and the validation message.

The  selector property is obviously required, otherwise the validator can never be called. However, the  validateshow and  clear are optional. For example, if a form element is already being validated through an existing validator, you can update the UI behavior of the error message by registering a new validator with only  show and  clear functions. Order of registration is important; the last validator registered is the first validator used. View the  Granite UI Validation documentation for further information. AEM's default validators are located at  /libs/granite/ui/components/foundation/clientlibs/foundation/js/validation/validations.js

The most obvious reason for providing custom show and clear functions is to validate a custom dialog component. For example, in the AEM Touch UI Validation Library, the two functions are used in the multifield validator as the field used is an HTML textbox to validate and it's not in the same HTML structure as the other HTML textboxes that the default AEM validator has already registered.

The benefit of using the provided jQuery.validator plugin is that it becomes trivial to create custom validation with a consistent UI provided by AEM out-of-the-box. As you write your custom validators, note that the jQuery.validator plugin attempts to mimic the default HTML5 validation and more importantly, note that hidden fields are not validated.

AEM provides a simple jQuery API to interact with form elements:


Using the principles described in this blog post, I've created the AEM Touch UI Validation Library to provide enhanced validation to Granite dialog components such as the multifield, browserpath, radiogroup and autocomplete.
Create a custom Granite UI adapter to disable the Multifield component.
Adobe Experience Manager's Granite UI introduces the concept of Adapters. Adapters are a client-side device inspired by Apache Sling's Adapters and its adaptTo method. Adapters are an easy and clean way of creating APIs for commonly used functionality associated with specific objects. Adapters attach functionality to DOM elements according to vocabulary. Vocabulary is analogous to Java Interfaces.

The first Adapter that you're likely to encounter is the foundation-ui. The foundation-ui is an object, adaptable from the global window object, that gives you the power of creating Coral UI alerts, notifications, prompts and loading indicators. Try copying the following JavaScript into the console of any Touch UI authoring page.

Granite UI alert triggered by foundation-ui adapter.


There are a variety of adapters which you can find in the Granite UI documentation. There are more adapters that are not listed in the documentation such as the foundation-clipboard which allows an easy API to write to local and session storage. So be sure to explore /libs/granite/ui/components/foundation/clientlibs/foundation/js.

It's easy to write your own adapters. Granite UI foundation components come with the foundation-field vocabulary. However, in this example we're going to create an improved adapter with an API that will completely disable the component by disabling the add button, all input fields, the remove and the drag-and-drop reorder buttons. We'll also add an additional method to enable/disable only the add button which could be useful in applying a max limit to the Multifield component.

Touch UI dialog with multifield disabled through the custom adapter.


Use the foundation-registry adapter to gain access to the Registry API where you can register a new adapter. The type property is the name of the adapter. The convention is to use the application name followed by the topic. The selector attribute identifies eligible objects, usually a DOM element or the window object. The target object to be adapted need not be obtained by using the declared selector, but it must satisfy the selector. The adapter property is where the public APIs are defined and executed.

In this example, we actual register three separate adapters. The Multifield component is essentially a composite of other components, so we'll use the parent adapter to delegate functionality to the children component's own adapters. Input fields such as textfields and selects can use the provided AEM foundation-field adapters, however, we needed to create new adapters for standard buttons as well as drag-and-drop reorderable buttons. The new adapters were created using the application's namespace rather risking collision with future AEM updates.

To make use of the API, use jQuery to get the Multifield component, adapt it to the custom vocabulary and run the custom disabled method.


Multiple adapters can be created for any selector. The AEM provided foundation-field adapter is still available to the .coral-Multifield selector even when the example code is used. To make your adapter available when authoring in the Touch UI, ensure that it's in a clientlib that identifies the cq.authoring.dialog category.