This Confluence has been LDAP enabled, if you are an ASF Committer, please use your LDAP Credentials to login. Any problems file an INFRA jira ticket please.

Child pages
  • GSoC 2010 mini-CMS project

Versions Compared


  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Migrated to Confluence 5.3


Table of Contents

Overview (from SLING-1438)


See for the full list of GSoC 2010 projects at the ASF, and for general GSoC information.


Apache Sling is an opensource project with a lot of technologies and features. The goal of this project is to create a mini-CMS, that developers can use to understand how to develop a simple application with Sling. So it is necessary to know a little about two main topics: OSGi and JCR. The following links are useful resources to read something about these technologies.


The repository for this project can be found at

Some words about David Mini CMS

This project shows some features of Apache Sling and can be used for educational purpose to move your first steps with this framework.

David uses the following opensource library/technologies:



Node creation is a simple task, but you must understand how you can render the information stored in the nodes using Sling.
The first document you can read is the next one:
It . It simply describes how content resolution works in Sling. 


Content loading

You can setup some initial contents that can be used in your application. It is a useful thing, because with a simple configuration you have some nodes already created when your application starts.


JSON isn't the only way to load initial content. Further informations about content loading can be found in the Content Loading Bundle Documentation.

Create new entry

There is a script that provide this basic function, /apps/david/new.esp. As you can see in David I choose the ESP scripting language, but as we already said, you can choose among a lot of scripting engines with Sling. This script loads two other script files, used in every script of David: /apps/david/header.esp and /apps/david/menu.esp. These scripts, as the name suggests, contain header informations and the menu for David. 


So we loaded these two scripts in new.esp. In addition to this, in this script we defined a simple form, with some input text texts and a CKEditor panel. 

Once the user fills the input, the page is like in the following image


If we click on the button and everything goes well, we will see a popup with the text "Entry saved" and our article will be in the repository at the path /content/david/YEAR/MONTH/DAY/somethingliketitle.

As you can see, there isn't a definition for the name of the entry but anyway we will have this entry is it possible?


If the resource doesn't exist, a new item is created. If the resource name ends with /* or /, the name of the item will be created using an algorith that also uses the name of new node. The creation of the new node goes through the SlingPostServlet , a frontend for the content manipulation. This servlet provides also other content operations, as described here.

In the HTTP POST request there are also some others fields:

  • sling:resourceType=david : This information is stored on the new node, so when we will retrieve this node from the browser, using any extension (for example .article provided by /apps/david/article.esp ) Sling will search under the folder /apps/david. 
  • jcr:mixinTypes=mix:referenceable : Another information that will be stored. In that way this node can be referenceable. This feature will be useful for the tags management.


You can submit new entry only if you have already authenticated with Sling. So you can see that on the /apps/david/menu.esp script there is a check for the credentials


Let's now explain this code. Using the sling.js, system utility defined in Sling, we can get the session information object. If the userid of this object is anonymous we put a link to the authentication form.


The authentication form receives a resource parameter, that is the resource where the user will go after the authentication. This sort of authentication is a basic one, if you want to know more about authentication in Apache Sling you can read the authentication documentation on Sling website.


The delete operation is an easy task, because we only have to make a HTTP POST request to the article URL, with a special parameter :operation=delete.

This request is made with a jQuery function bounded to the DELETE link, as you can see in the /apps/david/list.esp script


Being an OSGi Component there is the implementation of activate and deactivate methods, which is called when the component is activated/deactivated.

TagGenerator class implements EventListener interface, so in the onEvent method we add the tags of the created node to the tagging structure.

When we delete a node, we can see that there is another AJAX call in the /apps/david/list.esp script before the real removal. There is a call which uses the :operation=deletetag parameter.

This operation is implemented by David, using the sling.gsoc.david.operation.DeleteTagOperation class. In Sling you can define new operations extending SlingPostOperation. The new operation is defined with the constant as we can see in the next code

Code Block
@Property(value = "deletetag")
static final String OPERATION = "";


To create this XML there is another registered component, which manages the cloud resource type. This component is sling.gsoc.david.servlet.CloudExtension , which extends SlingAllMethodsServlet to manage this new resource type. In the following code of this component you can see how it is used the @Property annotation to configure it