Assuming to know the structure of an AEM or Sling site within the logic of the site can cause problems.First, never assume to be able to know the root of the site or the names of sibling pages within code. Second, don’t parse the URL of a page to determine page information, such as language.
What does this mean? And why can’t the developer, of all people, know for certain what the structure of a site is?
A big part of Sling way of defining the Web site is the separation of content from the logic. By design, content can be created and removed without changes to the site’s logic. Sometimes content is associated with logic by path, but usually the relationship is through the resource type of the content.
Even so, couldn’t a developer take for granted that names of the nodes in a site have functional meaning? Say, for example, the page being rendered has the url, http://mysite.com/en/men/summer/special.html. By parsing the URL, you may suppose that the page has Summer-oriented merchandise for men in English. But the page could be a special sale of left-over Winter merchandise. The page can be a listing of women’s or children’s gifts that are targeted to male buyers. Or the ”special” of the page is a Spanish translation of items especially suited selected from the English-language catalog. Within Adobe Experience Manager and Apache Sling, the content author and the logic developer can work independently of one another. The root page of the site looks to be http://mysite.com/en, but there may be several entirely different sites under the node and the true root of the site could be http://mysite.com/en/men or ,even, http://mysite.com. We come back again to the separation of content from logic. The organization of content is not controlled by the logic developer. Never expect a content author to know and abide by a developer’s page naming guidelines. Depending on guidelines makes the site fragile and prone to breaking when there are misspellings and mistakes.
Another pitfall of assuming to know the structure of the site is that AEM has the ability to create different versions of the same content as a “live copy.” The original site may very well have the URL the developer expected, but the live copy will have a completely different URL, despite sharing the same logic. Apache Sling does not have the live copy framework, but the concept can be applied in a similar way. The content author can create variations of content that will not be same as the original content.
So don’t use the path as a source of properties. And don’t require a particular structure for a site.
The reason people do this is because of their need to evaluate the taxonomy of specific content based on its location in the content. To not sound contradictory, that is not a bad thing and not an anti-pattern. In fact, it is a supposition made because content is in a tree structure. It can be thought of as being an inherent design pattern for Apache Sling and AEM.
It is a valid design pattern to assume that the properties of a node applies to all of its children. The top-level page of a site can be marked with the locale of US English. All of the components within its content node do not have to have their locale indicated as well. And it is valid to suppose that all of its child nodes share the same property. All child nodes can be assumed to have the same locale.
Jörg Hoh writes about the anti-pattern of assuming site structure and provides a corresponding valid design pattern for Apache Sling and AEM that serves the same purpose. Use node properties for providing information about site structure and walk up a node’s parent tree to find what properties the node inherits from the tree structure of the site. If the user does not have permission to read a node in the parent tree, its properties should not be available. And if there are parent nodes that are significant, such as the root of a site, set a property on these nodes as a flag. To determine the root node, iterate through the parent tree until the root node property flag is found. The same can be done for other types of inherited traits. Have a property that specifies whether the merchandise in that section is for men, women, or children. To discovery the merchandise type of a page, see if that property is set on the page itself. If not, iterate through the parent nodes until the merchandise type property is found.
Jörg Hoh provides more detail about this anti-pattern and its corresponding design pattern on his blog, Things on a content management system: AEM anti-pattern: The hardcoded content structure.