Components below /libs/cq/gui/components/authoring/dialog are meant to be used only in the Editor (component dialogs in Authoring). If they are used elsewhere (such as in a wizard dialog for instance), they may not behave as expected.

Structure

The basic structure of a component is covered on the page AEM Components - the Basics. This section covers both the touch-optimized and classic UIs - even if you do not need to use the classic settings in your new component it can help to be aware of them when inheriting from existing components.

Extending Existing Components and Dialogs

Depending on the component you want to implement it might be possible to extend or customize an existing instance, rather than defining and developing the entire structure from scratch.

When extending or customing an existing component or dialog you can copy or replicate either the entire structure or the structure required for the dialog before making your changes.

Extending an Existing Component

Extending an existing component can be achieved with Resource Type Hierarchy and the related inheritance mechanisms.

Remarque :

Components can also be redefined with an overlay based on the search path logic; but in such case, the Sling Resource Merger will not be triggered and /apps must define the entire overlay.

Remarque :

The content fragment component can also be customized and extended, though the full structure and relationships with Assets must be considered.

Customizing a Existing Component Dialog

It is also possible to override a component dialog using the Sling Resource Merger and defining the property sling:resourceSuperType.

This means you only need to redefine the required differences, as opposed to redefining the entire dialog (using sling:resourceSuperType). This is now recommended method for extending a component dialog

Defining the Markup

Your component will be rendered with HTML (Hyper Text Markup Language). Your component needs to define the HTML needed to take the required content then render it as required, on both the author and publish environments.

Using the HTML Template Language

The HTML Templating Language (HTL), introduced with AEM 6.0, takes the place of JSP (JavaServer Pages) as the preferred and recommended server-side template system for HTML. For web developers who need to build robust enterprise websites, the HTML Template Language helps to achieve increased security and development efficiency.

Remarque :

Although both HTL and JSP can be used for developing components for the touch-optimized UI, we will illustrate development with HTL on this page, as it is the recommended scripting language for AEM.

Developing the Content Logic

This optional logic selects and/or computes the content to be rendered. It is invoked from HTL expressions with the appropriate Use-API pattern.

The mechanism to separate logic from appearance helps clarify what is called for a given view. It also allows differing logic for different views of the same resource.

Using Client-Side HTML Libraries

Modern websites rely heavily on client-side processing driven by complex JavaScript and CSS code. Organizing and optimizing the serving of this code can be a complicated issue.

To help deal with this issue, AEM provides Client-side Library Folders, which allow you to store your client-side code in the repository, organize it into categories and define when and how each category of code is to be served to the client. The client-side library system then takes care of producing the correct links in your final web page to load the correct code.

Configuring the Edit Behavior

You can configure the edit behavior of a component; this includes attributes such as actions available for the component, characteristics of the inplace editor and the listeners related to events on the component. The configuration is common to both the touch-optimized and classic UI, albeit with certain, specific differences.

Configuring the Preview Behavior

The WCM Mode cookie is set when switching to Preview mode in the touch-optimized UI; even when the page is not refreshed.

For components with a rendering that are sensitive to the WCM Mode, they need to be defined to refresh themselves specifically, then rely on the value of the cookie.

Remarque :

In the touch-optimized UI only the values EDIT and PREVIEW are used for the WCM Mode cookie.

Creating and Configuring a Dialog

Dialogs are used to allow author to interact with the component. Using a dialog allows authors and/or administrators to edit content, configure the component or define design parameters (using a Design Dialog)

Customizing a dialog is similar to developing a component as the dialog is itself a component (i.e. markup rendered by a component script together with behavior/style provided by a client library).

For examples, see:

/libs/foundation/components/text/cq:dialog

/libs/foundation/components/download/cq:dialog

Remarque :

If a component has no dialog defined for the touch-optimized UI, then the classic UI dialog is used as a fallback inside a compatibility layer. To customize such a dialog you need to customize the classic UI dialog. See AEM Components for the Classic UI.

If you consider your dialog as a simple container for a form element, then you can also see the primary content of your dialog content as form fields. Creating a new form field requires you to create a resource type; this is equivalent to creating a new component. To help you in that task, Granite UI offers a generic field component to inherit from (using sling:resourceSuperType):

/libs/granite/ui/components/foundation/form/field

More specifically Granite UI provides a range of field components that are suitable for use in dialogs (or, more generally speaking, in forms).

Remarque :

This differs from the classic UI, where widgets are represented by cq:Widgets nodes, each with a particular xtype to establish the relation with their corresponding ExtJS widget. From an implementation viewpoint, these widgets were rendered on the client-side by the ExtJS framework.

Remarque :

Such components are still written in JSP and not in HTL, because form fields are a special case. This is because they rely heavily on passing values from one script to another through the request, an action that is not possible in HTL (at the moment). Therefore, form fields (as an exception) should still be written in JSP.

Once you have created your resource type, you can instantiate your field by adding a new node in your dialog, with the property sling:resourceType referring to the resource type you have just introduced.

Creating a client library for style and behavior

If you want to define styling and behavior for your component, you can create a dedicated client library that defines your custom CSS/LESS and JS.

To have your client library loaded solely for your component dialog (i.e. it will not be loaded for another component) you need to set the property extraClientLibsof your dialog to the category name of the client library you have just created. This is advisable if your client library is quite big and/or your field is specific to that dialog and will not be needed in other dialogs.

To have your client library loaded for all dialogs, set the category property of your client library to cq.authoring.dialog. This is the category name of the client library that is included by default when rendering all dialogs. You want to do that if you client library is small and/or your field is generic and could be reused in other dialogs.

Listeners in a custom client library

Define, in your client library a JS listener hooked on that CSS class name (this ensures that your custom logic is scoped to your field only, and does not affect other fields of the same type).

To achieve this you need to know about the underlying widget library that you want to interact with; see the Coral UI documentation to identify which event you want to react on (this is very similar to the process that you had to perform with ExtJS: find the documentation page of a given widget, then check the details of its event API).

Listeners in the content structure (classic UI)

In the classic UI with ExtJS, it was usual to have listeners for a given widget in the content structure. Achieving the same in Touch UI is different as JS listener code (or any code at all) is no longer defined in the content.

The content structure describes the semantic structure; it should (must) not imply the nature of the underlying widget. By not having JS code in the content structure, you can change the implementation details without having to change the content structure. In other words, you can change the widget library without needing to touch the content structure.

Field Validation

Mandatory Field

To mark a given field as mandatory set the following property on the content node of your field:

Using the AEM Brackets Extension

eases synchronization (no Maven or File Vault required) to help increase developer efficiency and also helps front-end developers with limited AEM knowledge to participate on projects.

provides some HTL support, the template language designed to simplify component development and increase security.

Remarque :

Brackets is the recommended mechanism for creating components for the touch-optimized UI. It replaces the CRXDE Lite - Create Component functionality, which was designed for the classic UI.

Migrating from a Classic Component

When migrating a component that was designed for use with the classic UI to a component that can be used with the touch-optimized UI (either solely or jointly) the following issues should be considered:

HTL

Use of HTL is not compulsory for the touch-optimized UI, but if your component needs updating then it is an ideal time to consider migrating from JSP to HTL.

You will need to create a new dialog for use in the touch-optimized UI. However, for compatibility purposes the touch-optimized UI can use the definition of a classic UI dialog, when no dialog has been defined for the touch-optimized UI.

Migrating cq:listener code

If you are migrating a project that was designed for the classic UI, then the cq:listener code (and component related clientlibs) might use functions that are specific to the classic UI (such as CQ.wcm.*). For the migration you must update such code using the equivalent objects/functions for the touch-optimized UI.

If your project is being completely migrated to the touch-optimized UI you need to replace such code to use the objects and functions relevant to the touch-optimized UI.

However, if your project must cater for both the classic UI and the touch-optimized UI during the migration period (the usual scenario), then you need to implement a switch to differentiate the separate code referencing the appropriate objects.