Welcome to the codeflair blog!

Here, you can find interesting bits and pieces we find in our work and about codeflair itself.


 

AEM TouchUI dropdown mandatory validation

2. Juni 2017
Christoph Thommen

In AEM 6.2, there is no mandatory validation for dropdowns in dialogs, when having a „Please select“ option in place. This is due to a validation check in the out of the box AEM validator which does a check for „value != null“, which is not the case when having a „Please select“ option (value would just be a blank String).

There is currently no other option then implementing a custom validation. This requires the following steps:

  1. Create a new clientlib with the following configuration
  2. Add the following JavaScript to this clientlib. This JS validates all select fields with a specific property set (see step 3)
  3. To mark select fields as required (and enable this validation), put the property validation=“select.required“ on it:
     

TouchUI Page Properties encoding issue with AEM 6.2 CFP3

2. Juni 2017
Christoph Thommen

While implementing a new website based on AEM 6.2 CFP3 for a customer, we faced the following problem:

When editing page properties right from „Sites“ > „View Properties“, the encoding of special characters got lost/wrong. When editing the same page from via „Edit“ > „Page Properties“, everything worked well.

This resulted in corrupt data:

The reason for this problem: In the „View Properties“ dialog, the _charset_ property is missing which is required by AEM to determine the proper encoding of the submitted form data.

There is an easy fix for this:

By adding a hidden field named „_charset_“ to the page properties dialog with the value „utf-8“, the problem is solved:

 

AEM 6.2 Image Upload Dialogs

15. Januar 2017
Ben Zahler

When migrating to AEM 6.2 (we’re using SP1), the dialog for uploading images (or any other file) may not work with your existing configuration.

Affected are dialog items with sling:resourceType=“granite/ui/components/foundation/form/fileupload“.

The fix is very easy: Simply add this property to the configuration node:

In the documentation Adobe describes field uploadUrl as „The URL where to upload the file, you can use ${suffix.path} to use the current suffix“. It seems that value ${suffix.path} is what you need to put to get the default behavior.

However, there is another catch: in our tests, setting the image/file upload to mandatory breaks the functionality.
To make it work, remove the following property if present:

Hopefully, Adobe will fix this soon…

here is a full configuration of the upload item that works for us:

Right-To-Left Keyboard Switch for Granite / Touch UI

30. Dezember 2016
Ben Zahler

In the AEM classic UI, an author entering text in Hebrew can switch the editor to right-to-left mode with the keyboard shortcut ctrl-shift-x.

Unfortunately, this is not possible anymore in AEM’s granite or touch ui. While it sounds strange to create a keyboard shortcut to a touch ui, it is still helpful to have that ability when working from a desktop or laptop computer, so here is a package that implements this functionality:

rte-rtl-switch.zip

This works in both the inline and the full screen rich text editor and has been tested in Internet Explorer, Chrome, Firefox and Safari.

Simply install to you AEM instance using the package manager and the keyboard shortcut works.

enjoy!

Serving Assets with Selectors

12. August 2016
Ben Zahler

In a project, we recently had the requirement to serve assets with a selector. The reason for adding the selector was that all CUG protected assets need to be served from an specific dispatcher farm.

Unfortunately, the extension of assets is part of the node name in AEM. A sample geometrixx asset is stored as node „GeoCube_Datasheet.pdf“ under /content/dam/geometrixx/documents .

When we try to access this with a selector /content/dam/geometrixx/documents/GeoCube_Datasheet.secure.pdf, the resource cannot be resolved, resulting in a 404.

After checking the Sling source code, we’ve found a way to get to the document with the selector: add all the selectors after the extension, and then add extension .res.

Why? that’s quite complicated:

  • adding the selectors after the original extension makes sure that the resource is actually found during resource resolution
  • rendering of resources needs to be done by the org.apache.sling.servlets.get.impl.helpers.StreamRendererServlet, but the servlet only accepts resources without an extension or with .res

But our troubles are not quite over yet: If we render this as a .res resource, Apache will serve this as content type application/x‐dtbresource+xml

The following rewrite rule should take care of that for pdf documents:

With this rewrite rule, the asset is actually available for end users at the desired url /content/dam/geometrixx/documents/GeoCube_Datasheet.secure.pdf, hiding the .res extension workaround from the end user.

 

Why components are not shown the in CoralUI Component Browser

18. Mai 2016
Christoph Thommen

When developing new components in AEM 6.0/6.1 for the new CoralUI frontend you might end up in components not beeing shown in the Component Browser, even if they would be allowed to place on the current page based on the Design configuration.

When are components shown in the Component Browser / Sidekick?

  1. Component is allowed to be placed on the current page (Design configuration)
  2. Component is not hidden
  3. Component has a Dialog OR
  4. Component has a cq:editConfig

Why are components that are matching the criteria not shown in AEM 6.1 Coral UI

Components which are allowed to be placed on the page, are not hidden and do have a valid cq:dialog configuration (CoralUI dialog configuration), will not be shown in the Component Browser nor in the Sidekick. The reason for that is:

The Component Browser is still looking for the existence of the („old“) extJS dialog.xml configuration. If there is no dialog.xml configuration, the component won’t be shown in the list.

How to resolve this issue

Instead of creating a dialog.xml which will never be used, a simple cq:editConfig can be created to make the components visible again:

 

Do you need assistance in upgrading to CoralUI or a new AEM version? Just let us know!

Duplicate SSL Filter Bundle in AEM 6.0 SP2 and SlingHttpServletRequest.isSecure()

3. September 2015
Ben Zahler

In AEM 6.0 SP2, there is a new version of the „Apache Felix Http SSL Filter“ bundle.

Unfortunately, it has a different package name as the one included in AEM 6.0, which means that both versions of the SSL Filter are active.

SSL_Filter

Now if both filters are active, the second filter does not have the information if originally, the request was sent over https or http.

Therefore the SlingHttpServletRequest.isSecure() method will always return „false“.

This is fixed if the old (0.0.1.R1394715) version of the filter is disabled, one way to do this permanently is the use of the AEM Commons OSGI disabler.

 

unsatisfied AEM components because of duplicate package names

24. April 2015
Ben Zahler

Today, I had an issue, where some of my AEM components just would not start. They had „unsatisfied“ service references, but the referenced services were up and running.

After a lot of searching and thanks to this blog post, I finally found out that the actual problem was that the referenced services’s package name was identical to a package name in my component’s bundle.

So what happened?

Let’s say my Interface was set up like this:

  • bundle name: codeflair-blog-api
  • Interface name: ch.codeflair.blog.api.BlogInterface.java

Package ch.codeflair.blog.api.* was exported and therefore the interface was made available by the bundle.

My implementing class ch.codeflair.blog.impl.BlogInterface.java was set up in a different bundle, let’s say codeflair-core-impl. In this bundle there was another (completely unrelated component) which implemented interface ch.codeflair.blog.api.ConflictingInterface.java in bundle codeflair-core-api.

codeflair-core-api also exported ch.codeflair.blog.api.*, and because the bundle also had a dependency on codeflair-blog-api, all classes from package ch.codeflair.blog.api in codeflair-blog-api were copied to bundle codeflair-core-api and also made available in that bundle. Now our ch.codeflair.blog.api.BlogInterface.java is availabe in two different bundles, so an adapter factory will not recognize that ch.codeflair.blog.impl.BlogInterface.java  actually implements ch.codeflair.blog.api.BlogInterface.java from codeflair-blog-api.

So the bottom line is: choose a good package struckter und really make sure a package is neever user in two different bundles!

AEM / CQ assets with xmpRights:WebStatement

4. Februar 2015
Ben Zahler

if a DAM asset has property xmpRights:WebStatement set (usually automatically extracted from the file during the import workflow), CQ redirects to the value in the property, assuming that the property contains the path to a page where the user has to accept a license agreement for the asset.

Note that this only happens when the asset directly is accessed, but not when specific renditions are accessed.

To switch off this behavior, access the system console’s config for the BinaryProviderServlet:

http://localhost:4502/system/console/configMgr/com.day.cq.dam.core.impl.servlet.BinaryProviderServlet

Uncheck the option „Enable Digital Rights Management“ and your assets are displayed correctly!

 

Limiting allowed cq:tags-path within namespaces

13. Januar 2015
Christoph Thommen

A common issue when working with CQ tags is the lack of possibility to limit the user entering only specific trees of tags within a namespace in a specific TagInputField.

Example

We have a tag structure like:

  • /etc/tags/search/keyword/…
  • /etc/tags/search/client/…
  • /etc/tags/search/…/…

Now we want the user to enter keywords (and only keywords) in the page property field „Keywords“.

The issue we’re no facing is, that in CQ only allowed namespaces can be limited, but not paths inside a namespace.

 

To solve this, the following listener attached to the TagInputField in the dialog.xml might help:

This listener is fired each time a tag is added to the TagInputField. The listener checks if the tag is located inside the desired path (in our case „/keyword“). If not, it will be removed again immediately.

 

This is a really easy way to restrict TagInputField to certain tag paths.