Over a million developers have joined DZone.

Creating a Contact List App With Apache Sling

Francisco Ribeiro shows us how to use the Apache Sling web framework and builds a simple application.

· Java Zone

Navigate the Maze of the End-User Experience and pick up this APM Essential guide, brought to you in partnership with CA Technologies

In this post we will create a Simple Contact List App using Apache Sling. This simple example will show how to use some sling tag libraries and the sling post servlet to create content in the repository.

To create this example we used the HTML from this snippet.

Setup the Application

In order to create our application the first step is to create our Maven project.

We will use the sling-intitial-content-archetype archetype like we did in a previous post.

The only difference is on the folder strucutre and the Maven configurations.

Our project structure can be seen below:

Project Structure

The changes in the Maven configuration:


Explaning a little bit more:

  • /apps: contains our rendition scripts, basically where our node contents sling:resourceType will point to;
  • /etc/sling-contact-list: contains our static files, JS and CSS.
  • /content: contains our content. The main node is contactsapp with the resourceType set to sling-contact-list/contacts-index

The contacts-index.jsp is the script that will render our main page.

Integrate the HTML

Before starting working with the dynamic content from the repository, we started by adding the static HTML and the assets(js, css).

To hold our static assets we’ve created a new folder(sling-contact-list) under /etc.

Then we created our rendering script under apps, and in the JSP just put the static HTML in it.

This step is important to check if we added all the required assets to the static HTML works.

Creating the Contacts in the Repository

Our first step in our application is to create the contacts in the repository. For this we will use the built-in Sling Post Servlet. This is a default servlet provided by Apache Sling to handle POST requests. By using this servlet we can create/modify and delete content in the repository without the need to create any backend code.

A simple example can be seen below:

<form method="POST" action="http://host/some/new/content" enctype="multipart/form-data">
   <input type="text" name="title" value="" />
   <input type="text" name="text" value="" />

With this simple form it will create (in case it doesn’t exist) or update the node /some/new/content by setting the title and text in the node.

All the possibilities of use of this servlet can be seen in the Apache Sling Docs.

In our code we will show some of the properties we can use with it.

We can see our form code below:

<form action="/content/contactsapp/contacts/*" method="post" enctype="multipart/form-data">
                        <fieldset class="form-group">
                            <label for="name">Name</label>
                            <input type="text" class="form-control" id="name" placeholder="Enter your name" name="name">
                        <fieldset class="form-group">
                            <label for="email">Email address</label>
                            <input type="email" class="form-control" id="email" placeholder="Enter email" name="email">
                            <small class="text-muted">We'll never share your email with anyone else.</small>
                        <fieldset class="form-group">
                            <label for="address">Address</label>
                            <input type="text" class="form-control" id="address" placeholder="Enter your name" name="address">
                        <fieldset class="form-group">
                            <label for="phone">Phone</label>
                            <input type="text" class="form-control" id="phone" placeholder="Enter your phone" name="phone">

                        <fieldset class="form-group">
                            <label for="contactImage">File input</label>
                            <input type="file" class="form-control-file" id="contactImage" name="contactImage">
                        <input type="hidden" name=":redirect" value="/content/contactsapp.html" />

                        <button type="submit" class="btn btn-primary">Submit</button>

Let’s see the important parts:

form action="/content/contactsapp/contacts/*" 

With this action in the form, we are saying to create a new node under the contactsapp/contacts node. The path ending with / or /* says that the node that will be created will have an auto generated name.

<input type="hidden" name=":redirect" value="/content/contactsapp.html" /> 

With the :redirect we specify where to redirect after the POST processing. In our exemple we are saying to get back to the home of our application.

The other input[type=“text”] fields will set the node properties. The only exception is the input[type=“file”]. Instead of setting node properties, it will create a node under the contact node created. This node will have nt:resource as its jcr:primaryType.

As we didn’t specify the jcr:primaryType of the node we are creating, it will be created as nt:unstructured.

To test our form, we need to deploy our application:

mvn clean install -P autoInstallBundle 

Then access:


We can see our form below:

Contact Form

After filling the form fields and choosing an image, we can see the nodes created by using the explorer: 

Node Properties

As we can see, it set the properties in the node created under contacts and also created a new one called contactImage that contains the image uploaded. Also, we can notice that it takes the name input value to create the node name.

Great! Let’s take the next step.

Displaying Our Contacts

To display the content we are storing in the repository we will change the contacts-index.jsp and we will use some taglibs and EL functions provided by Sling. We can find the taglib documentation here.

Firstly, we need to declare the taglibs by adding this to the JSP:

<%@taglib prefix="sling" uri="http://sling.apache.org/taglibs/sling" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>

We are going to use the Sling and JSTL taglibs.

Then we need to add this tag:

<sling:defineObjects /> 

This tag defines objects that are regularly used when we are scripting the pages. Among the objects we have:

  • resource: the current resource;
  • slingRequest: SlingHttpServletRequest object;

In our exemple we will use only the resource object.

Basically our contacts will be stored under the contacts node that is under contactsapp node. Our app is accessible by this url: /content/contactsapp.html, so the resource object will represent the contactsapp node.

The main idea in the JSP is to get all nodes under /content/contactsapp/contacts and display their properties.

To retrieve the contacts node we will use the EL function: sling:getRelativeResource. We can see its use below:

<c:set var="contactsResource" value="${sling:getRelativeResource(resource,'contacts')}" /> 

This code retrieves the path contacts relative to the resource. As we said before, our resource is contactsapp, so this code retrieves the contacts node under it.

Once we have the node that holds all our contacts, we need to get the list of all child nodes. For this we will use another EL function: sling:listChildren. We can see it below:

<c:set var="contacts" value="${sling:listChildren(contactsResource)}" /> 

With this we are getting all child nodes and storing in the contacts.

After this we just need to iterate over the list using the c:forEach tag

<c:forEach var="contact" items="${contacts}" >
    <sling:adaptTo adaptable="${contact}" adaptTo="org.apache.sling.api.resource.ValueMap" var="contactProps" />
    <c:set var="contactImage" value="${sling:getRelativeResource(contact,'contactImage')}" />

We are not showing the whole loop, in this part we have one new tag: sling:adaptTo. This tag get an object and adapt it to an instance of the class defined in the adpatTo property. In our case we are adpating the Resource object into a ValueMap object to make easier to get the node properties.

In the other line we use the getRelativeResource to get the node that holds the image: contactImage.

Once we have the valueMap contactProps and the image, we can display the contacts properties:

<img src="${contactImage.path}" alt="${contactProps['name']}" class="img-responsive img-circle"> 

The properties we get as keys from the valueMap and the image path we use the contactImage node path. All the other properties are retrieved the same way.

After deloying our changes, we can see them working in the image below:

Image title

You can find the source code at my GitHub page.

That’s it for today. I hope you enjoyed the post.

Thrive in the application economy with an APM model that is strategic. Be E.P.I.C. with CA APM.  Brought to you in partnership with CA Technologies.

apache sling,maven,jstl,tags

Published at DZone with permission of Francisco Ribeiro, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}