Sling Resource Resolution and AEM - Part 2
Veena Vikraman
Adobe Experience League Community Advisor (AEM). Adobe Certified AEM Architect and Senior Developer. Python , React Beginner.
I really want to share my understanding on this topic as I have seen a lot of developers in AEM struggle to understand how exactly a script/file is executed , when a content is rendered. Trust me it's not any rocket science. It is just some well written rules. That is what Sling Resolution is all about as far as I understand. If we understand these rules , it is simple. So what can we do ???? ? How about putting ourselves in SLING shoes (?? that's how I tried to learn SLING when I was taking my baby steps. I used to act like I am SLING and trace the path from one node to another in terms of SLING, till I clearly understood. It might sound funny I know ??)
Why don't we go for another walk in SLING ?? and try to understand this concept ? Let's give it a try
To help you understand this , let's do some initial setup in our local AEM instance. As I always do , I have setup the WKND project in my local. ( It has complete project setup with code , content and everything we need.)
Find it here :- https://docs.adobe.com/content/help/en/experience-manager-learn/getting-started-wknd-tutorial-develop/overview.html
Now once the setup is done, make sure you have all the pages up and running. In this article I am assuming your AEM is running on port 4502 . Else, replace the below URLs with your corresponding ports.
Now let's take example of a page . I like tacos ?? so I am going with https://localhost:4502/content/wknd/en/restaurants/best-tacos-in-the-city.html
Now, as you enter the above URL in the browser , you surely get a page rendered with a lot of content. So how does this content get rendered with everything in the correct place ? ???? ever wondered ?
If I quote the words from the official Sling documentation
Request Processing?— Sling takes a unique approach to handling requests in that a request URL is first resolved to a resource, then based on the resource (and only the resource) it selects the actual servlet or script to handle the request.
Resources?— The central mantra of Sling is the?Resource, which represents the resource addressed by any request URL. It is the resource that is first resolved when handling a request. Based on the resource, a first servlet or script is then accessed to actually handle the request.
Coming back to our example, let us just take a walk along the footsteps of SLING on how it is going to resolve our URL and is going to render our page for us.
As you can see this resolves to a cq:Page. So the next thing SLING will look for is a content node of type (cq:PageContent) and name(jcr:content). If that is not found, an error will be thrown. A page will only become a valid resource if has below structure
page
(type:cq:Page)
--
|
jcr:content (type-> cq:PageContent)
So as SLING, I know I should be looking at the cq:PageContent child node( which should be surely of name jcr:content) of a cq:Page node for proceeding further ahead to resolve this request. - I have to correct myself here . A little more on how SLING actually decides to go to jcr:content from cq:Page node. Read this article here :- https://cqdump.wordpress.com/2019/01/07/how-does-sling-resolve-an-aem-page-to-the-correct-resource-type/ (Jorg has explained it very well. They are the experts I look up to ??)
So our next stop is this
Okay now a little confession time ???? When I used to take training for AEM , I used to tell the developers that if we have a relative path, then in AEM, SLING will look for the resources first under /apps and then under /libs ?? . I won't say that is wrong. It was and is correct but the point is no one asked me why and how ? And as I was just exploring things at that time , I would not have been able to answer the question if they have asked ???? . But then if you have a similar question now, I would say take a look at https://aemmastery.com/aem-osgi-service-dive-resource-resolver-factory-c2521f75be51
As I have mentioned before there are certain principles or rules by which SLING delivers the content and those are mostly defined in such OSGI configurations as the one above. ( I might not have 100% info on all of them )
Now how the script is resolved from this resource !?.
For the same take a look at https://sling.apache.org/documentation/the-sling-engine/url-to-script-resolution.html . I know many things will be little over the head for any fresh developer. But don't worry now. I will try to put that to you in a layman's term as much as I can.
If you finished reading the above URL , let me simplify the same here in simple words
Below are the best matches in the order
1. page.html
2. html.html
3. sling:resourceSuperType
4. GET.html
Now, when I say best match what does that mean ? If one file is not present , then the next one gets precedence. So in this you might have noticed the 3rd match. Yes , you read it right, I said sling:resourceSuperType . Why ? Before SLING fallback on finding the default script (GET.html / POST.html) , it gives a last try to see if there is any file which it can pull from an inherited component. And how ? that's what sling:resourceSuperType does. Treat it like a parent component to your component. If any script is not present in your component , and it has a sling:resourceSuperType , then SLING will go and take a look at that component in a similar manner to find if any script can be resolved to render content. Read the same here in this JIRA ticket for SLING issues.
领英推荐
As per the above JIRA ticket
Add support to the Servlet Resolver to resolve scripts not just for the resource type but also
for the super type (if defined). This super type resolution takes place before falling back
default scripts !
Yes it has. So now we have to take a detour to our parent , which is core/wcm/components/page/v2/page
( I know you might be tired walking this long path ?? but guess what , that is the exact route SLING takes each time we send a request to our AEM publish. This is just a starter ??. We are yet in the process of finding the page rendering script.But for SLING, under one page there might be a lot of components and it take the exact same steps for each of those resource. )
Now when I go to /apps/core/wcm/components/page/v2/page and follow the exact same Sling Resolution Principles , I know that the first file/script which is going to execute will be the page.html
( disclaimer :- PARENT and CHILD are my way of identifying these components to avoid confusion)
Let me make this little more understandable , let us open the page.html from /apps/core/wcm/components/page/v2/page and try to trace the path which we think SLING will be following. Let us open page.html . I have marked few lines from that file
Same goes for all the files marked till 7
Now let us see what will happen when footer.html is rendered in line 28 ( marked 6) . Lets open the footer.html
The highlighted section is where I want to take your attention to. You can see a file include there right ? SLING has to include the contents of customfooterlibs.html at this location. From where will the contents be fetched .
We have one under /apps/core/wcm/page/v2/page ( Our PARENT)
We have a same name file under /apps/wknd/components/structure/page ( Our CHILD)
Which file do you think will be executed ??? Think for a moment .
Did you say CHILD !? ??exactly !!! ... Why ? Because when SLING sees a script include in a file in the PARENT , it first go to the CHILD, look for a same-name file , if it finds, it will be executed, else it will come back and look it under PARENT. Same with PARENT too, if it finds the same-name file/script under PARENT, it will be executed. If it doesn't find it in any of those place , it will throw error ( unless there is another sling:resourceSuperType on PARENT .. Nope.. I am not even gonna take that route now ????)
I will leave the rest of the SLING resolution for this component with you guys . If you have understood what I was trying to explain till now, then rest will be a piece of cake for you ???. Even still you are confused , drop a comment or send me a message , I will try to explain it to the best of my knowledge.
I hope I didn't confuse much but was able to convey the concept properly if not completely.
Uff ??. This was a real long one than I expected. I guess I need some coffee now..
Oh yeah, please let me know of any corrections or suggestions. I am all ears for you ??
Edit 1 :- Added the link to understand how exactly the jcr:content is resolved to render the page . Read it here https://cqdump.wordpress.com/2019/01/07/how-does-sling-resolve-an-aem-page-to-the-correct-resource-type/ .
As I have told prior I am no expert , all the articles are purely my understanding of the topic. So please correct me if any one see anything wrong or missing in these articles. I surely don't want to send wrong information out there.
AEM Developer
3 年Awesome, thx a lot for such a detailed explanation!