AEM dialog with extraClientlibs – do not shot yourself in the foot

AEM dialog with extraClientlibs – do not shot yourself in the foot
The below steps will help you to avoid common mistakes during implementation

There is a common case when we have to extend the AEM component dialog with custom JS code for some cases: field custom validation, to load external data, update field value on any condition, and so on.

Everything is going well until we have a few components or JS logic is not greater than the “hello world” component. But when the project grows alongside with components number we will face dependency hell.

In the scope of components dialogs, we have to keep in mind that every custom include of “extraClientlibs” will live on the page until page reload therefore JS functions could easily break logic in other dialogs during the page editing.

The below steps will help you to avoid common mistakes during implementation:

  1. DO not include every custom JS client library into the cq.authoring.dialog category:
    categories="[cq.authoring.dialog]"

    This ClientLibs category has to be used ONLY for utility methods that could be used across all dialogs and wouldn’t break anything.

  2. Every component dialog with custom JS code have to be placed in a separate category, easy to use package or folder path as a category name, this prevents category name overlap:
    categories="[project-a.components.product.wizzard.authoring]"
  3. Make a rule to put validation that we are working with the required dialog at the JS beginning, if not – bypass the execution:
    (function (document, $) {
    
    "use strict";
    
    const DIALOG_RESOURCE_TYPE = "project-a/components/product/wizzard";
    
    function isTargetDialog($formElement, dlgResourceType) {
    	const resourceType = $formElement.find("input[name='./sling:resourceType']").val();
    	return resourceType === dlgResourceType;
    }
    
    $(document).on("dialog-ready", function () {
    	const $formElement = $(this).find('coral-dialog form.foundation-form');
    	if (!isTargetDialog($formElement, DIALOG_RESOURCE_TYPE)) {
    		console.debug("Skip the listener, not a ", DIALOG_RESOURCE_TYPE, " dialog.");
    		return;
    	}
    	...
    });
    })(document, Granite.$);

As we can see these three steps will help to keep code clean and maintainable.

Enable AEM Javadoc hints

To consume the whole power of IDE we must use Javadoc hints. Below is a short “how-to” on how to enable these hints for AEM 6.4:

  1. Open “Project structure” (short-key on Windows: Ctrl + Alt + Shift + S):
  2. Find the “Maven: com.adobe.aem:uber-jar:apis:6.4.4” (or another uber jar which you are using for the project) and click plus icon with the Earth

  3. Put the “https://helpx.adobe.com/experience-manager/6-4/sites/developing/using/reference-materials/javadoc/index.html” as a documentation URL.

After all of these actions you’ll be able to see API doc hints (on Windows with Ctrl + Q) :

How to simplify AEM UI developing

In AEM very often we need to synchronize content (html, css, dialogs, nodes and so on) between local AEM instance  and development environment. We can achieve this in a few ways:

  1. deploy content bundle every time when we need content refresh with maven (common approach)
  2. use some IDE with built-in functionality for synchronization (Eclipse with Sling IDE plugin, Brackets)

There is also exists another way which I’m referrer to synchronize content – to use Jackrabbit FileVault (VLT) which introduces a JCR repository to filesystem mapping.

Let me show in few steps how to configure it (I believe all console commands are self-explained): Continue reading “How to simplify AEM UI developing”

New Configuration Approach for AEM 6

Since OSGI R6 we can beautify old style configurations for AEM 6 and create more readable, maintainable and loosely coupled code. In this target Declarative Services 1.3 (DS 1.3)will assists to us. Let’s consider how this can be reached step by step in scope of AEM 6 and Java 8. I wouldn’t provide a long description with explanation all pros and cons of this approach, what Declarative Services is and other things. Anyway you can simply google it if it’s interesting for you. Continue reading “New Configuration Approach for AEM 6”

Create Adobe AEM project from scratch in 5 steps with Apache Maven

When newcomer starts to develop a new project the question arises in the rapid establishment of a skeleton for future application. Every AEM project other than “Hello World” should contains server-side business logic, environment specific configurations, page templates, component templates, unit and tests and so on. To keep all this code clean and maintainable we should group it into small pieces (modules). The best practice is to hold Java classes and other content separately. Here we come to the aid of the Apache Maven. Continue reading “Create Adobe AEM project from scratch in 5 steps with Apache Maven”

JCR-SQL2 Query with Examples

Introduction

OOTB Apache OAK allow to create queries on SQL(deprecated), XPath(deprecated), JCR-JQOM and JCR-SQL2. It’s obvious that there is not a good point to explain deprecated SQL and XPath. This is a little How-To article which try to cower JCR-SQL2 queries for Apache Jackrabbit/OAK. Apache OAK has a more strict JCR-SQL2 syntax therefore some queries which are working correct on Apache Jackrabbit wouldn’t be executed on Apache OAK so we should always hold this in mind. Anyway let’s deal with JCR-SQL2 queries.
Continue reading “JCR-SQL2 Query with Examples”

How to make JSP scriplets on Java 7, Java 8 and above on Apache Sling and Adobe AEM

Sling implementation allow to render JSP with scriplets (of cause we using scriplets instead of Groovy console for hot-fixes). By default JSP compiler allow to write code compatible with Java 6 therefore if on server we has JVM version greater than 6 and desire to write code for recent JVM with additional benefits like Diamond operators from Java 7 or Lambdas and Streams from Java 8 we should configure JSP Scripts Handler to process required Java version otherwise we will see the compilation error: Continue reading “How to make JSP scriplets on Java 7, Java 8 and above on Apache Sling and Adobe AEM”

How to deal with request parameters encoding in AEM

When Sling receiving a request from any submitted form it parses it in two phases:

  1.  Sling get raw input data and identity transform bytes to chars as the original data was in ISO-8859-1 encoding.
  2. Locates _charset_ parameter which should be specified in every submitted form. This parameter specify form data original encoding. On second phase encoding will be resolved as:
    1. All names of the parameters are re-encoded
    2. The parameter values are re-encoded, unless the parameter value is an uploaded file. Actually the parameter (not the files of course) are internally as byte[]() where the conversion to a string is done on the fly (and yes, the conversion using the _charset_ character encoding is of course cached for performance reasons)
    3. If the parameter is an uploaded file, the file name is re-encoded on the fly when accessed

Good news that _charset_ parameter in Sling up to 2.2.4 is optional, so we can omit it. In this case second phase will resolve encoding based on sling.default.parameter.encoding property within org.apache.sling.engine.impl.SlingMainServlet.

Note: if sling.default.parameter.encoding wasn’t specified – second phase wouldn’t be reached and all not ASCII submitted text data will be encoded incorrectly.

For configuration sling.default.parameter.encoding we should open /system/console/configMgr/org.apache.sling.engine.parameters and set appropriate Default Parameter Encoding value:

configure_request_parameters_encoding_in_aem

How to close user session after inactivity in AEM or Apache Sling

When user request the site Sling back-end will instantiate a new session for it or using previously opened (Of cause this is a common case for application server). But a lot of opened sessions can impact performance therefore not active sessions must be closed. Time of inactivity depends on business requirements. For close user session after inactivity we should:

  1.  Open configuration path:
    /system/console/configMgr/org.apache.jackrabbit.oak.security.authentication.token.TokenConfigurationImpl
  2. Set appropriate value for Token Expiration property (Expiration time of login tokens in ms.)
    Configuration for Close user session after inactivity in AEM