This is AEM development best practices. These practices do not cover standard like jsp, js & java development practices. This is an effort to consolidate our learning in CMS domain.
2. AEM Components
JSP’s
• Avoid Text In JSP Files
• One of the goals of using CQ5 is to enable the author to author the text that is displayed on the web
site. Hardcoding text strings in jsp files prevents that goal from being met.Variables that derive their
values from dialog widgets should be named the same as the widget
o If a dialog has a pathfield called url Path, for example, the variable that gets
this value should also be called url Path.
• Allow CQ to write image tags whenever possible using img.draw(out)
• By default, CQ will output name and alt properties as the same name the image has in the DAM. Set a
user defined alt tag with setAlt().
3. Conti……
Code Style
• Avoid using jsp:useBean to set the page context. It only creates a singleton bean in the page
context. Thus using the same component more than once on different pages will create bugs.
• Instead import the page using <%@page import=" the page you want the context from" /%> and
use the jstl tag <c:set var="" value="" scope="" /> to set the pages context.
• <%@page session="false" %> to avoid "IllegalStateException Page needs a session" errors
in the logs. (for JSP's commonly used across many pages, this can cause 80% of the logged
exceptions on production publish instances). All global-*.jsp files include this, so it maybe free if
you @include them..
4. Conti…..
Code Style
• Avoid javax.jcr.Node in JSP's - there are better abstraction layers:
● properties, pageProperties [org.apache.sling.api.resource.ValueMap] to get node property
values
● Resource, Resource.adaptTo(ValueMap.class) gives equivalent to above, especially if you need
to getParent/child/something
• try {...} catch(Exception) {...} is a code smell. Generally, shouldn't have to handle exceptions in
JSP's, so look for alternative API's, or work with better, safer structures.
• If your render script needs complex logic based on the properties of the resource being
rendered or its descendants, you should create a component model to extract the logic into a
java/groovy class.
5. Develop for authors.
Context
• Create a user interface that allows the author to edit content within the context of the resulting page. Add
author cues whenever possible (red/italics text for areas a user needs to add content if not apparent).
Dialogs / widgets
• When creating a dialog, the first panel should always be the most dominant content of the final output. In
most cases, this is the image associated with the component.
• A SmartImage widget should be used for any images that will be main pieces of content. When creating
smartimage widgets, ensure there is a corresponding resType node.
Use Templates to provide default page structure
• A template contains a jcr:content (cq:PageContent) node which is used to initialize the content of pages
created from the template. So, multiple templates can be used to provide the author different options for
default content for the same underlying page type.
6. Develop for Reusability
Develop at the smallest level
Break a component down to its smallest logical parts. For example, if a component has a call to action
button, text area, headline and a background image, it will often make the most sense to develop each
of these components individually and assemble them under an composite component. This a.) keeps
dialogs small; and b.) ensures maximum reusability.
Favor composition over inheritance
If you want a list-image component for example, don’t take a list component, copy it, and hack it to have an
image. A reasonable approach is to create a new component and add the necessary components to it.
When you upgrade CQ to a new version, you’ll have no changes to make – it’ll automatically use the
new version. (From Antony Hutchinson)
Reuse dialogs in composite components
If a new component is necessary because it is not possible/feasible/best to stack a bunch of components on
top of each other for UI reasons, reuse the dialogfrom the simpler component to ensure a consistent
editing experience across all like components.
7. Conti….
Remove Style Specific Class Names from Component JSPs
Avoid using style specific class names (like "blue") in the component JSPs which prevents the
components from being used in different places and on different sites. Wherever possible, these
kinds of class names need to change to reflect the structure of the component (like "label") not
how it should be styled
Overlay to extend the functionality of out-of-the-box components
Avoid modifying anything under /libs. Avoid copying anything from /libs to /apps. Extend the
functionality of out-of-the-box components by overlaying them.
8. BackEnd Models (Java & groovy)
• Sling Model
• Java/Groovy Bean
• When to create model:
- If the JSP is just accessing properties on the Resource, do NOT create a model.
- If you have to do more processing but there is a logical way of doing it without a model (e.g.,
creating custom tags), do that and do NOT create a model.
- If you have processing that needs to be done and there is just no other reasonable home, then
you should create a component model object as a home for it.
9. Java/Groovy best practices
If designing an object, make sure that it does exactly one thing
• Corollary: If you're adding a method to an object, make sure that it's the right place to put it. It's not a
bad thing at all for an object to have only one method if that's the best way to keep things cohesive.
• If you're passing more than a small handful of parameters (~4) into something, it's a very good bet
that the method is doing too much. Of course merely sidestepping the problem (such as passing in
an object that is then deconstructed as if the parameters had been passed in individually) doesn't
help. If it can't be cleanly cleaned up, the object itself if likely doing too much.
• Use the semantics of the type and collections systems.
• JodaTime is a preferred API vs the crappy Java DateTime stuff for anything involving dates if
possible
• Never declare an implementation collection type for a variable when you can use a more generic
interface instead
• For instance, do not declare a variable as a type of HashMap: use Map instead
10. JavaScript Best practices
• Javascript that implements component behavior should be packaged in the form of a jquery plugin defined
in an immediately invoked function expression (iife):
;(function($){
"use strict";
$.fn.component = function(opts) {
var options = $.extend({
// plugin options set here
// option1 = 'value',
// option2 = 'value'
}, opts);
return this.each(function() {
// component implementation
});
};
}(jQuery));
11. Conti…
• The component plugin should be attached to each instance of the component specifically. This can most
easily be done by generating a unique id that can be used as a selector in the jsp file:
<script>
jQuery(document).ready(function() {
jQUery('.component').plugin();
});
</script>
• Always declare and use namespaces for all Javascript objects, which we'll call packaging. Do not write
objects without packages.
• Var Havells = Havells || {};
• Havells.Package = Havells.Package || {};
• Havells.Package.formatNumber = function() {
};
• Havells.Package.constants = {
'name1' : 'value1',
'name2' : 'value2'
};
12. General Javascript Coding Practices
• Explicitly use "var" when declaring variables. This refines the scope, is better for predictability, and
increases performance.
• Use single quotes instead of double-quotes when declaring values (i.e. var val = 'value')
• Do not include trailing commas in JSON or JS objects, because IE will not compile the JavaScript
file.
• Javascript should be well factored. Common functions should be moved to <Project>.Utils.
Common objects can be created in apps/responsive/residential/javascript.
• On publish instances, jQuery is loaded in the footer of the page where most JS is loaded. So
using the "$" short-alias for jQuery doesn't always work. Usually, the long-form "jQuery" is
necessary for triggering document.ready events.
13. CSS Best practices
• Do not include inline styles in an element's "style" attribute. Inline styles are difficult to override, and all styles should
be contained within and referenced from external CSS files.
• Do: <div id="content" class="bordered"></div>
• Do Not: <div style="border: 5px solid #ccc"></div>
• Never use an ID more than once in any given HTML document. Use class names to target more than one element.
• Use hyphens ("-") to separate multi-word class/ID names (i.e. "person-info-large". Do not use camelCase or
underscores ("_").
• For colors, attempt to use 3-digit hex codes before its 6-digit equivalent. For example, use "#aaa" instead of
"#aaaaaa". Do not use "gray" or word-based color values.
14. Conti..
• Distinguish between proper use of class-based CSS selectors vs ID-based selectors.
• classes
• Use to define elements that would reappear on multiple pages or templates
• Use to define elements that appear more than once on a particular page ids
• Use to target elements of a specific template that only applies to one page and would not apply to
other pages using the template.
• Use to target one particular element in a page that has identical class declarations as other similar
elements. For example, a list of <div class="item" /> elements where one element has ID "item-
322".