1. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
What is a
Reusable
Component?
Justin Edelson
Technical Architect
Adobe Consulting Services
2. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
About Me
3. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Why are we here?
4. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Why are we here?
5. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Let’s get one thing straight
6. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
7. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
8. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
9. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
10. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
11. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Parts of a Reusable Library
• AEM Components
– Dialogs, JSP / Sightly Scripts
• ExtJS Widgets / GraniteUI Components
• Data / Content Services
– Importers, Exporters, Integrations
• Common Configuration
12. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Models for Reusable Components
• Direct Reuse
– Primitives (Mostly)
– Example: Foundation Image Component
• Direct Reuse w/ Context
– Example: Foundation Column Control
• Extensible
– Designed for Extension per Project
– Example: Foundation List Component
• Sample
– “Pattern Library”
– Example: Geometrixx *
13. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Direct Reuse
• Minimal Markup
• Semantic Markup
– <section class="large-12 columns"></section>
• Text - i18n & Overrideable
• Intelligent Defaults
• …But Lots of Dialog Options
14. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
15. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Direct Reuse w/ Context - Tools
• componentstyles widget
– Example: Foundation Text Component
• slingscriptinclude widget
– Example: Page Properties Dialog, ACS AEM
Commons Generic Text Component
16. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
componentstyles
17. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
slingscriptinclude
18. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Extensible Components
• Component scripts are like Java classes
• Each include is a method
• Consider partials convention
19. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
20. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
21. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Anti-Patterns
• Dependencies on a particular CSS or JS
framework.
• Login/Registration–related components
• Lack of Governance
• Overly Aggressive Goals
22. CIRCUIT – An Adobe Developer Event
Presented by CITYTECH, Inc.
Notes de l'éditeur
Thousands
So before we get into it, let’s get one thing straight.
<click>
Developing reusable code is not easy. And it’s actually gotten harder, at least in the organizations I work with. I’m going to walk you through the evolution of a company I worked for. Your organization maybe hasn’t gone through exactly these steps, but I’m willing to bet you’ve ended up in the same place.
When I first started with web development, I worked in a very large media company with a dozen or so subsidaries – different cable channels, a book publisher, a chain of movie theaters, and so on.
<click>
This is a vastly simplified version of what our org chart looked like in 1996. We had an engineering manager and some developers. The engineering manager reported, maybe not directly like this simple diagram shows, up into the CTO. Then we had the Chief Marketing Officer, the title Chief Digtal Officer hadn’t been invented yet, who was driving requirements.
Then at some point, each subsidary got its own Chief Digital Officer.
This made things, shall we say… interesting because the engineering manager had to balance the needs of all of these different people. And at some level this was a zero sum game. There’s a fixed pool of developers and despite all the time we spend multitasking, we developers really are single-threaded.
So at some point this became untenable.
And this is what we ended up with. Each subsidiary now has their own engineering team. And in one case, the subsidiary has completely outsourced their development to an external agency. And since the engineering teams are part of the subsidiaries, the power dynamic between the CDO and the CTO has been inverted.
I should say that one deritive of this model is where one of the subsidiaries is the Intranet and the other is a public facing presence. In these cases, the Intranet team may very well report into the CTO. But I’d suggest that this doesn’t change the fundamental problem – you now have multiple disjoint development teams developing for the same delivery platform – the web. Add in mobile and we’re really in trouble.
And while the one development team had a resource contention problem, this model isn’t particularly efficient. For one thing, although each subsidiary has different requirements, logically they also have a lot in common so there’s a lot of duplication of effort going on here. And for another, if you disaggregate to this extent, you end up with multiple runtime platforms. Maybe Subsidary 3’s Agency likes Drupal and Subsidary 2 likes Wordpress and Subsidary 1 likes CQ (remember, this is in the past, so I’m still going to call it CQ).
So fast forward a bit and some organizations have realized that they need to have some kind of core or platform team responsible for core technology.
And, more often than not, this core team reports into the CTO. Which is either a good thing or a bad thing, depending upon whether or not you’re the CTO.
This takes care of the development site, but what about the runtime platform? Well… that’s where AEM comes in, right?
So once you standardize on AEM, what is the work of that core development team in AEM deployments? In general, that team is responsible for creating some reusable library.
In this library, you will typically see a few different things. The highlights include:
<click>
You have your literal AEM components which get added to a page, including dialog definitions and scripts.
<click>
You have some custom ExtJS widgets or now GraniteUI components
<click>
You have custom services, typically those with import or export content as well as integrate with third party systems.
<click>
Finally, you would have common configuration which is applied across projects.
I’m going to focus on the first item.
I see that there are four separate models for building reusable components. These aren’t necessarily mutually exclusive, but they are from my perspective useful buckets.
<click>
The first is direct reuse. So you have a component which can just be dropped into any site. These typically represent primitive elements – images, videos, text. The most obvious example of this is the Foundation Image component.
<click>
The second is direct reuse with some notion of site context. So again, the component can just be dropped into any site, but there is some extra bit of configuration which allows for some options to be defined per site or per template. The Column Control component is an example of this as it picks up the available column layouts from the design settings. Another example is the Generic Text component we have in ACS AEM Commons which obviates the need to create multiple text components because different sites want different options in the Rich Text Editor.
<click>
The third is extensible components. These may or may not be directly reusable, but they do make it easy for other components to be created which extend them. The best example of this in the Foundation components is the List component. Extending components can just create some scripts, following a particular naming convention, to define how items in the list appear.
<click>
And then finally, we have components which aren’t actually reusable, but are designed to illustrate a concept. These effectively form a pattern library, for example, if you want to implement a tab component, you should start by looking at the Geometrixx Outdoors Tabs component. Now to be honest, I think we can all agree that the Geometrixx components are of, shall we say, varying quality, so think of this as what they *should* be rather than what they necessarily *are*.
When building, or trying to build a resuable component, you should keep these things in mind.
<click>
The HTML your component produces should be minimal. The less HTML, the more likely that HTML will work across sites.
<click>
What markup does exist should be semantic. Which means, among other things, not embedding framework-specific classes like large-12 or col-md-6 or whatever. Foundation, Bootstrap, and specialty grid systems like Semantic dot GS support mixins to avoid this kind of dependency.
<click>
Reusable components shouldn’t include a lot of text, but what text does exist will generally need to be both internationalized and overrideable.
<click>
And in general, you want intelligent defaults
<click>
But a high level of customization, especially for complex components.
This is perhaps an extreme example, but here are some examples of a search component I built for a customer which was intended to be used across 5 different sites, all of which had different branding and features. As you can see, I had to allow for each site to decide how they wanted the search results displayed, how many results to display, as well as change the individual text pieces displayed on the results page.
When adding Context-specific features, there are a few tools you can use out of the box – the componentstyles and slingscriptinclude widgets, along with their Granite UI counterparts.
For those of you not familiar with the componentstyles widget, it allow you to declaratively define some styles in the design settings for a template and then make those styles available as drop-down lists in the component’s dialog <click> <click>. When an option is selected, it ends up in the cq CSS Class property, and then as an extra class on the container element.
The slingscriptinclude widget allows for a fieldset within a dialog to be dynamically generated. <click> <click> <click> These are some sample requests to populate Page Properties dialogs for a few pages and a Generic Text component. Since these requests are made to the page content node, you have a lot of flexibility in terms of what gets returned. <click> <click> Whether that be different fields or different options in the same fields or whatever.
When thinking about extensible components, I find it helpful to conceptualize of a component just like I would a Java class where each include is effectively a method. I also try to make the includes I expect extending components to override follow a convention where they go in a folder called partials.
Here’s the files which make up the ACS AEM Commons Audio component along with a very rough UML diagram.
Here’s essentially the same thing, but for the search component I referenced earlier.
I lastly want to touch on a few anti-patterns I’ve seen. These are things to avoid if you want to make reusable components. And if you find yourself needing to do them, you’ll be better off going more of the sample slash pattern library route.
<click>
I touched on this before, but avoid heavy dependencies on a particular CSS or JS framework. It’d be great if everyone could standardize on something, but it isn’t going to happen in my lifetime.
<click>
My experience has been that login and registration components are tough to reuse due to specific business rules.
<click>
Another anti-pattern is not having any governance structure for defining how reusable components are maintained. You can’t just throw a bunch of stuff together and call it a library. There’s management effort involved.
<click>
Finally, you should be realistic about how much reuse you are really going to get. Think about how many of the foundation components you actually use. And maybe reuse isn’t the right model for you.
I hope you’ve found this interesting. Have a great day and enjoy the rest of the conference.