Building an AEM Authoring Component out of HTL/Sightly; no JSP required!
Adobe gives us a ton of authoring components out of the box!
I mean, just look at them all in CRXDE 😲!
If you’ve spent any time on an AEM project you’ve no doubt composed component authoring dialogs using: Textfields, Switches, Multifields, etc. Adobe does a great job of providing almost everything a developer could need!
Occasionally though, we’ll need something a little more custom and on those occasions, datasource takes care of me 95% of the time.
For example, let’s say we have a Button/CTA component that needs to open up a modal/dialog. We can easily build a list of modal components on the page using a servlet and then provide that list via datasource:
fieldDescription="When clicked open Modal with corresponding id."
Straightforward and easy for a Content Author to use, right?
This article is for us 5%’ers who need something truly custom!
In my case, I have an SVG Sprite that contains all of the site’s iconography. If you aren’t using SVG Sprites (or aren’t familiar with the term), CSS Tricks is a great place to start but the gist is that you should probably be using SVG sprites over icon fonts.
Anyway, I needed a list of links where I could assign an icon to each link (if the author wanted). I didn’t want to display all icons, just ones appropriate for links. They also needed titles, just to help describe what the icon represented. The UI didn’t need to be anything special and I wanted it to fit with the CoralUI aesthetic so using a Coral.Select makes sense here.
Ultimately, this is what the end product looked like:
But before I could get there, I needed to figure out how to build authoring components. After some Google searching (and almost always ending up on the terse AEM docs or support forms) I gave up and decided to jump into the JCR and just look at how the text field works.
A render.jsp huh? Weird. So I looked for other, newer components. Same thing. Every authoring component was composed of a JSP. Even though HTL is the “preferred and recommended server-side template system for HTML in AEM”, all authoring components are built with JSP.
Why? Can we not use HTL to build authoring components? I scoured the internet for answers, but came up empty until I noticed a note on the Creating a New Granite UI Field Component doc page:
So I created an HTL component and tried it out! I looked at some other examples and quickly threw together an empty Coral.Select in the HTL…
… and I found out the docs were right! I had no easy way to get the value supplied from a content author. The properties object referenced the attributes on my XML tag:
So, I could create the entire UI for the component, but there was no way for me retrieve the saved JCR value supplied by a content author. Every time a content author opened the dialog, the component would act as if it had never saved. Obviously this was not a tenable solution.
So, I referred back to the docs (and looked at a few more JCR components for good measure) and found that this is the “magic” that JSP uses to pull in the JCR value for an authoring component:
So, theoretically all we need to do is gain access to that Field.class attribute on the request and then provide our components name (properties.name). So I attached a Sling model and used the debugger to peer inside the request attributes looking a “Field.class” to see if I could find my missing JCR data.
No dice. I was about ready to give up and submit to my JSP overlords when I reached out to my brother Tim Solum, who is a much stronger Java developer than I am (I’m supposed to be the Front-End AEM guy after all). After some additional poking around with Tim, we found my missing JCR data under FormData.class.
How/why did it change between the JSP and Sling Model? I have no idea. I chalk it up to AEM magic but if you have a better answer sound off in the comments 😊!
The resulting Sling model boiled down to a single reusable method that would grab all values for a given authoring dialog request:
From there, we could easily grab values for a given field like so:
I’ll update this article later with a few Github gists showing off all the source files so you too can be the proud owner of a custom, filterable icon select component!
Update: Here’s the Gist.
If anything is unclear, let me know below and I’ll try to clear it up. Otherwise, thanks for reading!