AEM Guide

Comment Sling résout une requête vers un composant AEM

Comment Sling transforme une URL en Resource puis en composant AEM via sling:resourceType, les search paths /apps et /libs, et pourquoi sling:resourceSuperType est le bon moyen d'étendre les Core Components.

slingresourcetypecore-componentshtl

Quand AEM affiche une page, ce qui se passe réellement en dessous est une résolution Sling en deux étapes : d’abord une URL devient une Resource, puis cette Resource devient un composant — un script HTL ou un servlet — qui décide du HTML renvoyé. Comprendre ce pipeline explique pourquoi /apps peut prendre le pas sur /libs, pourquoi les Core Components s’étendent via sling:resourceSuperType plutôt que d’être directement écrasés, et pourquoi un sélecteur mal placé peut casser le cache du Dispatcher.

De l’URL à la Resource

Quand une requête comme /content/monsite/fr/accueil.html arrive, Sling découpe le chemin en resource path, sélecteurs et extension, puis utilise le ResourceResolver pour associer /content/monsite/fr/accueil à un véritable nœud JCR. Dans un projet AEM, ce nœud est généralement une page (cq:Page), mais ce qui compte réellement pour le rendu, c’est son nœud jcr:content (ou celui d’un composant enfant), car c’est là que vit la propriété sling:resourceType.

De la Resource au composant : sling:resourceType

sling:resourceType n’est pas un chemin absolu : c’est un chemin relatif que Sling recherche dans une liste ordonnée de search paths. Par exemple, si un composant a :

sling:resourceType = "monprojet/components/hero"

Sling recherche un script (.html, compilé de HTL vers du Java en coulisses) ou un servlet dont le chemin, relatif à l’un des search paths, correspond à monprojet/components/hero.

Les search paths de Sling : pourquoi /apps passe avant /libs

La configuration par défaut de Sling (resource.resolver.searchpath) est ["/apps", "/libs"]. Cela signifie que pour un même sling:resourceType, Sling essaie toujours le script trouvé sous /apps avant celui trouvé sous /libs. C’est le mécanisme technique derrière l’« overlay » classique d’AEM : si une ressource produit se trouve dans /libs/quelquechose/composant et que vous placez un script dans /apps/quelquechose/composant, c’est le vôtre qui l’emporte.

Sur AEM as a Cloud Service, /libs est totalement immuable — vous n’y déploierez jamais rien. Cet overlay par search path reste réel pour certaines ressources de plateforme encore présentes sous /libs (des parties de Granite UI ou de la console OSGi, par exemple), mais ce n’est pas le mécanisme à utiliser pour étendre les AEM Core Components — et c’est une erreur fréquente.

Pourquoi les Core Components ne s’overlay pas : sling:resourceSuperType

Les AEM Core Components (core/wcm/components/...) sont livrés comme dépendance de votre projet et finissent installés sous /apps, pas sous /libs. Comme ils sont déjà dans /apps, vous ne pouvez pas les « battre » en plaçant quelque chose sur le même sling:resourceType sous /apps sans remplacer entièrement le composant produit — perdant ainsi toute amélioration future publiée par Adobe.

Le bon modèle est l’héritage de composants via sling:resourceSuperType :

<!-- /apps/monprojet/components/text/.content.xml -->
<jcr:root
    jcr:primaryType="cq:Component"
    jcr:title="Text"
    sling:resourceSuperType="core/wcm/components/text/v2/text"/>

Avec cela, votre composant monprojet/components/text hérite de tout ce que vous ne surchargez pas explicitement (dialogue, script HTL, Sling Model) depuis le resourceSuperType. Si votre script HTL ne définit pas un bloc donné, Sling remonte la chaîne de resourceSuperType jusqu’à le trouver dans le Core Component. C’est ce qui permet de ne personnaliser que les 10 % dont vous avez besoin sans dupliquer les 90 % restants.

Les sélecteurs et l’extension changent aussi le script choisi

Les sélecteurs et l’extension de la requête (.html, .json, un sélecteur comme .print) entrent aussi dans la résolution : Sling recherche d’abord un script spécifique à cette combinaison (text.print.html) avant de retomber sur le script par défaut (text.html). C’est exactement ce qu’utilise le JSON Exporter d’AEM (.model.json) pour servir la représentation Sling Model d’un composant sans toucher au script de rendu normal.

Où cela compte dans un vrai projet AEM