You are on page 1of 17

AEM Best

Practices
AEM Components
JSPs

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().
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..
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.
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.
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, dont 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, youll have no changes to make itll 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.
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.
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.
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
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));
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'
};
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.
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.
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".
AEM Page design.
- Parsys
- Column control
- Global stuff ( header/footer/ Menu)
- Ajax / Sling Resource resolver.
Others Practices

JCR Queries

Logging Configuration in CQ5

Prevent links from being checked on author system


Agenda
https://docs.adobe.com/docs/en/cq/5-6-
1/developing/developing_guidelines_bestpractices.html

http://training.bocoup.com/javascript-best-practices/

http://training.bocoup.com/writing-testable-javascript/
http://antonyh.co.uk/tag/best-practices/

http://docs.adobe.com/docs/en/aem/6-1/develop/the-basics/dev-guidelines-bestpractices.html

You might also like