AEM part1

Read our recommendations how to Build Complex Components with AEM Authoring Toolkit

Have you ever had a “Swiss Army Knife” component in your AEM project? Something that has many modes of behavior and many settings and is enmeshed in the current business logic? We bet you have, because we have dealt with this kind of component several times. A Swiss Army Knife can be anything, like a component that exposes individual products in a catalog in which product expositions differ from each other. It can also be a view of data that comes from different sources, each of which has a unique set up. Maybe your Swiss Army Knife is a component that has to support different adjustable layouts (like “show me these tiles as a grid, or a carousel, or a mosaic”) while working with the same data source.

No one builds a Swiss Army Knife from scratch (that would pretty clearly be against AEM best coding practices). Your component will start with a pretty compact design. It will then appear to be so handy that the business-side people will grow fond of using it and just ask to add a little tweak here, an option there… over and over and over again. The result will look great, and the component will get propagated to dozens of pages.

Everybody will see this component as a piece of cake except you, who will see a bowl of spaghetti.

At a basic level, complex code with many responsibilities ought to be split into singular elements. But when it comes to AEM components, the business side and the authors may, surprisingly, object. They generally prefer to keep working with the UI they are used to. They may loath to find a scattering of “Swiss opener,” “Swiss corkscrew,” and “Swiss little saw” where their Swiss Army Knife used to be. A greater number of separate components means more complicated template designs and policies, plus the need to migrate a multitude of legacy pages.

Is there a way to gently decompose complex components and keep the UX consistent and user-friendly all at the same time?

Yes you can, with the help of AEM Authoring Toolkit. Since you’re reading this article, you’re probably already familiar with this Exadel, Inc. product and have previously read our articles or the extensive manual on GitHub, so we won’t go into too much detail about the toolkit itself here. Instead, we’ll focus specifically on how it can help you in this scenario. Please take a look at this Java class and dialog (this is near some production code, but we’ve modified all the labels to keep up with the Swiss Army Knife metaphor).

AEM

The Toolkit automatically builds this dialog (see the annotations out there?). While this takes care of a huge chunk of our work, the dialog looks a bit messy.

You’ll see that there are settings that are kind of universal (like the brand name). There are some that refer to a couple of other options (like blades of a knife and probably scissor blades too, but not a corkscrew). There are also some that are effective only if another particular option is chosen.

Luckily we have a JavaScript supplement to marshal the visibility of components and wipe away redundant ones. The Toolkit offers a fantastic DependsOn feature to accomplish this task.

Let us show you a part of the code that can be modified:

The numBlades parameter makes sense if only the “cutting” facility is chosen. That is, numBlades depends on the value of canCut. To reflect this relation, we declare canCut as a kind of “variable” via @DependsOnRef and refer to it in @DependsOn(query = "@canCut", action = DependsOnActions.VISIBILITY). The latter means that the “visibility” prop has the same Boolean value as the value of canCut.

Note that we can apply more than one @DependsOn query to a field at the same time. The @DependsOn(query = "[email protected]", action = DependsOnActions.DISABLED) portion of the code prevents AEM from storing any value for a field when it’s not visible.

DependsOn queries consume complex conditions as well. This is what we see in the case of the logo field. Here’s how our dialog changes:

AEM
Looking cleaner now? Personally we’d say the mess is still there but the rubble has just been swept under the rug. It is still embarrassing if a user checks several boxes and opens a lot of secondary options at the same time. And it’s not easy to manage all of them from the back end, especially if every option needs a special kind of validation, processing, etc. Remember that we prefer to keep Java files below the 100-200 line limit!

Now it’s time to think of our Swiss Army Knife as a set of tools instead of a single one. The business side and the authors like to see them as a unit, but do they need to use them as one? Or do they just want an opener today, a corkscrew tomorrow?

From this point, we can start decomposing our component into sets of relatively independent features. These sets are presented as @FieldSets. They are each placed on a different Tab. This way the options are separated visually just like they are distinguished logically.

AEM

See that? Every feature set is a tab (we also have the initial tab for component-wide settings where the “brand name” resides). There is a Java class behind each feature set. The classes can extend each other so as to propagate the same settings to multiple feature sets without writing extra code (see the “engraved logo” field).

What if a user decided to fill in both logo fields in “knife settings” and “scissors settings?” They share the same field name, don’t they? Yes, but we can still distinguish between them with a prefix.

Consider the following code:

By adding a prefix to a fieldset we ensure that all its values will be stored with a modified name, in this case knife_logo and scissors_logo, along with knife_canCut, knife_numBlades, etc. The prefix can contain the slash symbol as well, manifesting the relative path! So, namePrefix = "knife/" would send all knife-related values to a “subfolder” named knife. This can be especially handy to monitor via CRX/DE.

You don’t even need to store the small “feature” classes within your component class. Extract them, and make them public if needed, and enjoy better code management.

Having a more neat and manageable Java code base is one thing the Toolkit was made for. Another one is improving the authoring experience. With that particular purpose in mind annotating the source code may just not be enough. But is there a way to make authoring dialogs more neat and laconic without the need to rethink the whole component structure?

Our next article will try to give an answer to that.

Author: Stepan Miakchilo

How can we help you?
Contact Us