I’m making a heavy use on the already existing tutorials on the Apache Sling’s website. Not because i want to be lazy about it, but because i think the Sling works quite different to what i have already seen. So i hope to extend the already existing documentation a bit and perhaps help to get a grasp on how Sling works. So, as prerequisite, i expect the Sling launchpad application and a Webdav client up and running.
This post centres around the way Apache Sling works in terms of rendering its content. This is the first part of two, which looks at content, resources and selectors in first place. Content is, by default, stored in Java Content Repository (JCR) conform data store. By default Apache Jackrabbit is used.
The interesting approach is the strict view on resources. Scripts, as Sling refers to views displaying and perhaps transforming data, can not be used without content. So, in order to understand the rendering of resources, one has to understand the way resources are addressed in first hand.
To start with the basics, we need content on the repository. To do so, we’ll use cURL to post data and create a new resource.
curl -u admin:admin -F"sling:resourceType=foo" -F"title=My content node" http://localhost:8080/content/bar
will do the job. This created a new node in the repository. When opening your browser of choice and access http://localhost:8080/content/bar.html, you’ll see a the default script executed and applied to the resource. I suggest getting the code to track back the usage of the HtmlRendererServlet to see that, depending on the suffix, other output formats are accessible as well, like XML or JSON.
Now, when trying to find the appropriate scripts, Sling will use the resource type to resolve a script under /apps/my/resource/type or /libs/my/resource/type. To verify the method, let’s create to new resources:
curl -u admin:admin -F"sling:resourceType=inapps" -F"title=Node displayed via script in apps." http://localhost:8080/content/in/apps
and
curl -u admin:admin -F"sling:resourceType=inlibs" -F"title=Node displayed via script in libs." http://localhost:8080/content/in/libs
When placing the following scripts in /apps/inapps
<!-- Place in /apps/inapps/GET.esp -->
<html>
<body>
<h1><%= currentNode.title %></h1>
<p>This script is located in the <code>/apps/inapps</code>.
It's path is resolved simply by using <code>GET</code>.</p>
</body>
</html>
<!-- Place in /apps/inapps/index.esp -->
<html>
<body>
<h1><%= currentNode.title %></h1>
<p>This script is located in the <code>/apps/inapps</code>.
It is adressed with the <code>index</code> selector.</p>
</body>
</html>
and these in /libs/inlibs
<!-- Place in /libs/inlibs/GET.esp -->
<html>
<body>
<h1><%= currentNode.title %></h1>
<p>This script is located in the <code>/apps/libs</code>.
It's path is resolved simply by using <code>GET</code>.</p>
</body>
</html>
<!-- Place in /libs/inlibs/index.esp -->
<html>
<body>
<h1><%= currentNode.title %></h1>
<p>This script is located in the <code>/apps/inlibs</code>.
It is adressed with the <code>index</code> selector.</p>
</body>
</html>
It gets obvious which scripts are resolved for each resource when calling the different urls:
- http://localhost:8080/content/in/apps.html
- http://localhost:8080/content/in/apps.index.html
- http://localhost:8080/content/in/libs.html
- http://localhost:8080/content/in/libs.index.html
The reason behind placing the scripts in these specific locations is because the engine will look by default into these paths.