COMPONENT HIERARCHY AND INHERITANCE

Component hierarchy is mentioned in ADOBE official component doucments

Components within AEM are subject to 3 different hierarchies:

1.Resource Type Hierarchy:

This is used to extend components using the property sling:resourceSuperType. This enables the component to inherit; for example a text component will inherit various attributes from the standard component.

  • scripts (resolved by Sling)
  • dialogs
  • descriptions (including thumbnail images, icons, etc)
  • Note: a local copy/instance of a component element will take precedence over an inherited element.

2. Container Hierarchy :

  • This is used to populate configuration settings to the child component and is most commonly used in a parsys scenario.For example, configuration settings for the edit bar buttons, control set layout (editbars, rollover), dialog layout (inline, floating) can be defined on the parent component and propagated to the child components.
  • Configuration settings (related to edit functionality) in cq:editConfig and cq:childEditConfig are propagated.

3. Include Hierarchy:

  • This is imposed at runtime by the sequence of includes.
  • This hierarchy is used by the Designer, which in turn acts as the base for various design aspects of the rendering; including layout information, css information, the available components in a parsys among others.

UnderstandingAEM mapping request to resource

Locate content resource

Resource path is used to locate content resource

  1. Sling checks weather a node exists at the location specified in the request(e.g. /content/articles/category-name/article-name.print.a4.html)
  2. If no node is found ,the the extension is dropped and search repeated (e.g. /content/articles/category-name/article-name.print.a4)
  3. If no node is found then return 404 http code

Locate scripts once content resource is located

  • The sling:resourceType is used to locate script to be used for rendering the content.
  • Scripts are located in /apps or /libs.
  • If certain rest method(GET, POST) is required, it should be specified in upercase within script name(e,g. a4.POST.jsp).
  • If multiple scripts apply for a given request

The script with the best match is selected. The more specific a match is ,the better it is; in other word, the more selector matched the better, regardless of any request extension or method name match.

Rules:

  1. Folder(e.g. nodes of tyope nt:folder) takes precedence over jsp file names when resolving using selectors, at least the first selector.
  2. Only one selector in a file name has effect, any file name contains two selectors don’t ever get selected, but name of folder can be used to match the selector in the request.
  3. Scripts with HTTP method names(e.g. GET.jsp) is selected as a last resort even after the default script(examples.jsp)
  4. The precedence of same name files are html > jsp > esp. E.g. if examples.html and examples .jsp both exist,then the examples.html will be shown.

For example: http://www.aemtreasury.com/content/resolution.print.a4.html/a/b?name=Dale of type sling:resourceType=”dale/example”

Assuming scripts structure as diagram below:

jcr_resolution

The order of preference should be as shown:

  1. /apps/dale/example/print/a4.html.jsp
  2. /apps/dale/example/print/a4/html.jsp
  3. /apps/dale/example/print/a4.jsp
  4. /apps/dale/example/print.html.jsp
  5. /apps/dale/example/print.jsp
  6. /apps/dale/example/html.jsp
  7. /apps/dale/example/example.jsp
  8. /apps/dale/example/GET.jsp

I prefer to make the script name is the same with fold name which is easy to remember, in this case is /dale/example/example.jsp

Note

Understand AEM URL decomposition

Rules of URL decomposition are list below

1. Resource Path

  • The longest substring of the request URL such that the resource path is either the complete request URL
  • Or the next character in the request URL after the resource path is a dot (.), which means the part between host and the first dot in the whole request

2. Selectors

  • If the first character in the request URL after the resource path is a dot,
    the string after the dot up to but not including the last dot before the next slash character or the end of the request URL.
  • If the resource path spans the complete request URL no seletors exist.
  • If only one dot follows the resource path before the end of the request URL or the next slash, also no selectors exist.

3. Extension

  • The string after the last dot after the resource path in the request URL but before the end of the request URL
  • Or the next slash after the resource path in the request URL.

4. Suffix Path

  • If the request URL contains a slash character after the resource path and optional selectors and extension, the path starting with the slash up to the end of the request URL is the suffix path.
  • Otherwise, the suffix path is empty. Note, that after the resource path at least a dot must be in the URL to let Sling detect the resource path.

5. Params

  • The key-value after queston mark(?).

For example, with the URL: http://www.aemtreasury.com/articles/category-name/article-name.print.a4.html/a/b?name=Dale

the URL can be broken down into composite parts:

protocol host path selector extension suffix params
https http://www.aemtreasury.com articles/category-name/article-name print.a4 html / a/b ? name=Dale

References:

  1. “URL Decompositon” section in https://docs.adobe.com/docs/en/aem/6-0/develop/the-basics.html
  2. https://sling.apache.org/documentation/the-sling-engine/url-decomposition.html

Configure the Rich text Editor

It is quit easy to configure the rich text editor as your requirement. The Adobe document is great.

<items jcr:primaryType=”cq:TabPanel”>
<items jcr:primaryType=”cq:WidgetCollection”>
<tab1
jcr:primaryType=”cq:Panel”
title=”Rich Text Editor”>
<items jcr:primaryType=”cq:WidgetCollection”>
<text-value
jcr:primaryType=”cq:Widget”
name=”./text”
xtype=”richtext”
height=”150″
fieldLabel=”Text Value”>
<rtePlugins jcr:primaryType=”nt:unstructured”>
<paraformat jcr:primaryType=”nt:unstructured” features=”*”>
<formats jcr:primaryType=”cq:WidgetCollection”>
    <paragraph jcr:primaryType=”nt:unstructured” tag=”p” description=”Paragraph”/>
     <heading-h2 jcr:primaryType=”nt:unstructured” tag=”h2″ description=”Heading h2″/>
</formats>
</paraformat>
</rtePlugins>
</text-value>
</items>
</tab1>
</items>
</items>

Access Sling Servlet/Service without requiring authentication

Yesterday, I tried to get a Json result from a Sling servlet, However I can’t get the result I want. Finally I figure out I need login first.

My solution is to use @Property(name = “sling.auth.requirements”, value = “-/bin/mysearch”, propertyPrivate = true) to to ensure the servlet can be accessed without requiring authentication.

@SlingServlet(paths = “/bin/mysearch”, methods = {“GET”})
@Property(name = “sling.auth.requirements”, value = “-/bin/mysearch”, propertyPrivate = true)
public class SearchArticlesServlet extends SlingSafeMethodsServlet {

…….
}

The Sling Authentication – Framework document does help a lot, it described below:

Anonymous Login

The SlingAuthenticator provides high level of control with respect to allowing anonymous requests or requiring authentication up front:

  • Global setting of whether anonymous requests are allowed or not. This is the value of the Allow Anonymous Access (auth.annonymous) property of the SlingAuthenticator configuration. This property is supported for backwards compatibility and defaults to true (allowing anonymous access).
  • Specific configuration per URL. The Authentication Requirements (sling.auth.requirements) property of the SlingAuthenticator configuration may provide a list of URLs for which authentication may be required or not: Any entry prefixed with a dash - defines a subtree for which authentication is not required. Any entry not prefixed with a dash or prefixed with a plus + defines a subtree for which authentication is required up front and thus anonymous access is not allowed. This list is empty by default.
  • Any OSGi service may provide a sling.auth.requirements registration property which is used to dynamically extend the authentication requirements from the Authentication Requirements configuration. This may for example be set by AuthenticationHandler implementations providing a login form to ensure access to the login form does not require authentication. The value of this property is a single string, an array of strings or a Collection of strings and is formatted in the same way as the Authentication Requirements configuration property.

The URLs set on the Authentication Requirements configuration property or the sling.auth.requirements service registration property can be absolute paths or URLs like the path service registration property ofAuthenticationHandler services. This allows the limitation of this setup to certain requests by scheme and/or virtual host address.

Examples

  • The LoginServlet contained in the Sling Auth Core bundle registers itself with the service registration property sling.auth.requirements = "-/system/sling/login" to ensure the servlet can be accessed without requiring authentication.
  • An authentication handler may register itself with the service registration property sling.auth.requirements = "-/apps/sample/loginform" to ensure the login form can be rendered without requiring authentication.

CQ Inheritance Model

CQ Inheritance Model is quite similar with Java. If the component inheritance is thought of as similar to Java’s class inheritance, then each script can be thought of as similar to a method.

  AEM CQ JAVA
Single Inheritance based on JSP’s, CQ is part of the Sling framework

and using the sling:resourceSuperTypefor setting the super type for a component

Class  extend from  parent class
Polymorphism Scripts defined within a “parent” resource may be “overridden” by a child by simply defining the same script.

This is very similar in concept to extending a Class and overriding a method by defining the same method name with the same signature

There is no concept of Public, Package Protected, Protected and Private. In Sling, everything is Public. Once a Script is defined, ANY Child may override it.

Class  inherits all the methods of a parent class. Parent methods can  be overridden

In general, by default, an empty component with nothing overridden will match exactly the super resource. However, if you add a JSP to your component matching the name of the super resource, that JSP will take precedence over the super resources, allowing you to override smaller portions.

Service vs Components in Felix OSGI

Component is less formally defined than services.

Service

Service is an object that is registered in the OSGi Service Registry and can be looked up using its interface name. The only prerequisite is that a service should implement an interface.  For example I can register a “CustomImpl” object under the “Custom”  interface, and clients could look it up using interface name (Custom)

Component

Component is object whose lifecycle is managed with any of the following features:

  • A component may publish itself as an OSGi service
  • A component may bind to or consume OSGi services
  • A component may be started and stopped; this would be considered an “active” component, though that is also an informal term. A component that doesn’t need to be started or stopped is called passive.

In general , using a component framework is the easiest way to work with OSGi services because the framework will manage the binding to the services that you want to consume.

For example , If a component “depends on” a particular service, in which case the component will only be created and activated when that service is available — and also it will be destroyed when the service becomes unavailable.