This is our first post in the Sling Gems series, that we'll use
to demonstrate our favorite Sling features.
In this episode, the SlingPostServlet
and the sling.js library are brought together using 46 (no kidding: fourty-six)
lines of code to create a simple blog (or let's say bloggish) application.
I used this example in my
Rapid JCR applications development with Sling
presentation at the last ApacheCon
(slides are available),
and I think it's a good testimony to the power and simplicity of Sling.
Step 1: Creating content
The easiest way to create content in Sling is to use an
HTTP POST request, let's use a simple HTML form to do that:
That's two input fields, a submit button and
a hidden field that tells Sling what to do after the POST (in this case:
redirect to the html view of the node that
was just created).
To test the form, start Sling and save the above script as
/apps/blog/blog.esp in the Sling repository - a WebDAV mount
is the easiest way to do that. Browsing to
http://localhost:8888/content/blog/*.html
should display the above form .
Input some data (using "foo" for the title, for the sake of
our examples below), save the form, and Sling
should display the form again, using the URL of the node that was just
created.
At this point you're probably looking at an empty form with an URL ending
in foo, if you used that for the title. Or foo_0 or foo_1
if other foos
already existed. Don't worry about not seeing your content, we'll fix that
right away.
Step 2: Where's my content?
To verify that our content has been created, we can have a look at the JSON
data at http://localhost:8888/content/blog/foo.tidy.json, which
should display our new node's values:
That's reassuring, but what we really want is for these values to be displayed
on the editing form for our post.
Thanks to the sling.js client library, we just need to add a Sling.wizard()
call to our form to display those values. Let's first add a <head> element
to our form to load the sling.js library, before the existing <body> of course:
And add the Sling.wizard() after the form, where we
had the code of step 2 comes here comment:
Reloading the form at http://localhost:8888/content/blog/*.html and creating
a new post should now redirect to an editable version of the post, with the form fields
correctly initialized.
We can now create and edit posts; let's add some navigation, using more of the
sling.js functionality.
Step 3: Navigation
The sling.js library provides utilities to access and manipulate content.
Four our blog, we'll use
the getContent(path) method to list the siblings of the current node.
Add the following code to your script, after the Sling.wizard() call that was added
in step 2:
The first link to /content/blog/* brings us back to our content
creating form, which is nothing else than the editing form reading empty
values and posting to the "magic star" URL.
The rest of the javascript runs client-side, as it is not embedded in
<% %> code markers, calls the sling.getContent
method to get two levels of node data below /content/blog, and
displays links to nodes that it finds.
That's a basic navigation, of course, in a real blog we'd need some paging and
contextualization to cope with large numbers of posts.
Nevertheless, with this addition our ESP script allows us to create, edit and
navigate blog posts - not bad for 46 lines of code, including comments, whitespace
and output formatting.
Step 4: Data first, structure later
You might have heard this mantra, which we apply in many areas of Sling.
In this case, adding a new field to our blog posts could not be easier:
just add an input field to the form, and Sling will do the rest.
Adding this inside our script's <form> element, for example:
Allows us to add an author name to our blog posts. No need to define anything at
the repository level, as Sling is using it in unstructured mode in this case, and
no need to migrate existing data, the author field of existing posts will simply
be empty.
I want my ESP!
Now wait...we said we were going to create an ESP script, but our "application"
is just static HTML and some client javascript at this point.
That's correct - as we are using only Sling client-facing features at this point
(HTTP POST and sling.js), we do not necessarily need to use ESP code.
To keep things simple, we'll refrain from adding ESP-based features
at this point, and keep that for a future Sling Gem.
That's the power of Sling
The 46-line blog is a good example of the power of Sling. It leverages
the SlingPostServlet, which handles POST requests in a
form-friendly way, and the sling.js
client library, which provides high-level functionality
on the client side.
A slightly fancier version of the blog.esp script is attached to this
post, the code is the same but some CSS makes it look a bit nicer.
Let us know what you think, and stay tuned for more Sling Gems episodes!