Return-Path:
This tutorial is based on the first Sling Gems on dev.day.com: The Sling gems: a blog in 46 lines of code. It has slightly been adapted to fit here. This tutorial is based on the first Sling Gems on dev.day.com: The Sling gems: a blog in 46 lines of code. It has slightly been adapted to fit here. In this tutorial, 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 http://us.apachecon.com/c/acus2009/sessions/284 presentation at ApacheCon US 09 in Oakland (slides will be available soon), and I think it's a good testimony to the power and simplicity of Sling. I used this example in my Rapid JCR application development with Apache Sling presentation at ApacheCon US 09 in Oakland (slides will be available soon), and I think it's a good testimony to the power and simplicity of Sling. Although this is a simple sample, it requires some custom settings to work. If you're just starting with Sling, SLINGxSITE:Discover Sling in 15 minutes might be a better choice. Although this is a simple sample, it requires some custom settings to work. If you're just starting with Sling, Discover Sling in 15 minutes might be a better choice. See SLINGxSITE:Getting and Building Sling for how to start Sling. Start it on port 8888 for the below links to work. For this sample we need the optional org.apache.sling.samples.path-based.rtp bundle, if it's not present in the OSGi console, install and start it. That bundle is not released yet so you might need to build it yourself, from its [source|http://svn.apache.org/repos/asf/sling/trunk/samples/path-based-rtp]. The bundle must then appear in the [OSGI console's list of bundles|http://localhost:8888/system/console/bundles], with name = org.apache.sling.samples.path-based.rtp and status = Active. Then, login using http://localhost:8888/?sling:authRequestLogin=1 which should prompt you for a username and password, use admin and admin. Once that's done, http://localhost:8888/index.html should say You are currently logged in as user admin to workspace default**. See Getting and Building Sling for how to start Sling. Start it on port 8888 for the below links to work. For this sample we need the optional org.apache.sling.samples.path-based.rtp bundle, if it's not present in the OSGi console, install and start it. That bundle is not released yet so you might need to build it yourself, from its source. The bundle must then appear in the OSGI console's list of bundles, with name = org.apache.sling.samples.path-based.rtp and status = Active. Then, login using http://localhost:8888/?sling:authRequestLogin=1 which should prompt you for a username and password, use admin and admin. Once that's done, http://localhost:8888/index.html should say You are currently logged in as user admin to workspace default**. The easiest way to create content in Sling is to use an HTTP POST request, let's use a simple HTML form: {code:html}
-
- 46 Line Blog
- Audience
-Step 0: Start, configure and login to Sling
-Step 1: Creating content
Sling microblog
<div> - <form method="POST"> - Title:<br/> - <input type="text" name="title" style="width:100%"/> - - <br/>Text:<br/> - <textarea style="width:100%" name="text"></textarea> - - <br/> - <input type="submit" value="save"/> - <input type="hidden" name=":redirect" value="*.html"/> - </form> -</div> - -<!-- code of step 2 comes here --> +-<html> + <body> + <h1>Sling microblog</h1> + + <div> + <form method="POST"> + Title:<br/> + <input type="text" name="title" style="width:100%"/> + + <br/>Text:<br/> + <textarea style="width:100%" name="text"></textarea> + + <br/> + <input type="submit" value="save"/> + <input type="hidden" name=":redirect" value="*.html"/> + </form> + </div> + + <!-- code of step 2 comes here --> + </body> +</html>-
-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 {footnote}ESP is Sling's server-side javascript language{footnote} in the Sling repository - a WebDAV mount is the easiest way to do that. Browsing to {footnote} This assum es your instance of Sling is running on port 8888. If that's not the case, adjust the example URLs accordingly. {footnote} 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. - -{note:title=AccessDeniedException?} -If you get an error saying _javax.jcr.AccessDeniedException: ...not allowed to add or modify item_ it means that you are not logged in as user _admin_. See instructions above for logging in. -{note} - -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 _foo_s already existed. Don't worry about not seeing your content, we'll fix that right away. - -h2. Step 2: Where's my content? - -To verify that our content has been created, we can have a look at the JSON data at , which should display our new node's values: - -{code:javascript} -{ +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 1 in the Sling repository - a WebDAV mount is the easiest way to do that. Browsing to http://localhost:8888/content/blog/*.html 2 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.
+{note:title=AccessDeniedException?} +If you get an error saying javax.jcr.AccessDeniedException: ...not allowed to add or modify item it means that you are not logged in as user admin. See instructions above for logging in. +{note}
+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 _foo_s 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:
+{ "jcr:primaryType": "nt:unstructured", "text": "This is the foo text", "title": "foo" @@ -145,14 +136,14 @@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:{code:html} -
- - -And add the after the form, where we had the _code of step 2 comes here_ comment: ++ -{code:html} -<!-- code of step 2 comes here --> +<head> + <script src="/system/sling.js"></script> +</head> +And add the
+Sling.wizard()
after the form, where we had the code of step 2 comes here comment:@@ -162,38 +153,31 @@<!-- code of step 2 comes here --> <script>Sling.wizard();</script>Step 3: Navigation
The sling.js library provides utilities to access and manipulate content. For 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:{code:html} -
Navigation
--
-- Create new post
- --Adding this inside our script's element, for example: -{code:html} -<br/>Author:<br/> +The first link to 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 method to get two levels of node data below , and displays links to no des 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. - -h2. 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. + </script> +</ul> +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 thesling.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:@@ -204,11 +188,20 @@<br/>Author:<br/> <input type="author" name="author" style="width:100%"/>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, but you can of course use any ESP code in the blog.esp "script".
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|http://svn.apache.org/repos/asf/sling/trunk/bundles/servlets/post/src/main/resources/system/sling.js]
client library, which provides high-level functionality on the client side.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.
-///Footnotes Go Here///
+ +Jackrabbit Persistence
-Jackrabbit Persistence
-Out-of-the-box the embedded Jackrabbit repository used by Sling (the Embedded Jackrabbit Repository bundle) uses Derby to persist the JCR nodes and properties. For some applications or environments it may be required or required to replace Derby with another backing store such as PostgreSQL or Oracle.
+Out-of-the-box the embedded Jackrabbit repository used by Sling (the Embedded Jackrabbit Repository bundle) uses Derby to persist the JCR nodes and properties. For some applications or environments it may be required or required to replace Derby with another backing store such as PostgreSQL or Oracle.
This page is based on the journey of Tony Giaccone to get Sling running with a PostgreSQL based Jackrabbit instance.
Management Summary
To replace Derby as the persistence manager for Jackrabbit the following steps are required:
@@ -94,8 +93,8 @@When you are not using the Derby persistence manager, you may safely remove the Derby bundle from your Sling instance.
JDBC Driver
-The hardest thing to do is probably getting the JDBC driver for your database. One option is to look at the bundles provided by Spring Source in their repository at http://www.springsource.com/repository/.
-Another option is to create the bundle on your own using Peter Kriens' BND Tool:
+The hardest thing to do is probably getting the JDBC driver for your database. One option is to look at the bundles provided by Spring Source in their repository at http://www.springsource.com/repository/.
+Another option is to create the bundle on your own using Peter Kriens' BND Tool:
- Get the JDBC driver for your database from the driver provider
- @@ -106,8 +105,8 @@ $ mv postgresql-8.4-701.jdbc3.bar postgr
Deploy the driver to your local Maven 2 Repository (Required if adding the JDBC driver to a Maven build, e.g. using the Sling Launchpad Plugin)
-$ mvn install:install-file -DgroupId=postgresql -DartifactId=postgresql -Dversion=8.4.701.jdbc3 \ - -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc3-bnd.jar
+$ mvn install:install-file -DgroupId=postgresql -DartifactId=postgresql -Dversion=8.4.701.jdbc3 \
+ -Dpackaging=jar -Dfile=postgresql-8.4-701.jdbc3-bnd.jarTony reports no success with the Spring Source bundle, whily the BND approach worked for the PostgreSQL JDBC driver.
@@ -116,14 +115,14 @@ $ mv postgresql-8.4-701.jdbc3.bar postgr
- Uninstall the Apache Derby bundle
- Install the JDBC bundle prepared in the first step
-- Stop the Jackrabbit Embedded Repository bundle\ +
- Stop the Jackrabbit Embedded Repository bundle
This needs to be reconfigured and restarted anyway. So lets just stop it to prevent failures in the next step.- Refresh the packages (click the Refresh Packages button)
Alternatively, you may wish to stop Sling after uninstalling Derby and installing the JDBC bundle. Technically, this is not required, though.
Reconfiguring Jackrabbit
To actually use a persistence manager other than the default (Derby) persistence manager, you have to configure Jackrabbit to use it. Create a
-repository.xml
file in thesling/jackrabbit
folder before starting Sling for the first time. If the repository was already started, you can also modify the existing file.To prepare a repository.xml file before first startup, use the
+[repository.xml]()
as a template and modify it by replacing the<PersistenceManager>
elements to refer to the selected persistence manager.To prepare a repository.xml file before first startup, use the
repository.xml
as a template and modify it by replacing the<PersistenceManager>
elements to refer to the selected persistence manager.If the file already exists, you can modifiy this existing file and there is no need to get the original from the SVN repository.
For example to use PostgreSQL instead of Derby modify the
<PersistenceManager>
elements as follows:<Repository> @@ -163,9 +162,9 @@ This needs to be reconfigured and restarIf you reconfigure Jackrabbit to use the new persistence manager, the existing repository data in the
sling/jackrabbit
directory, except therepository.xml
file, of course, should now be removed.Finally either start Sling or start the Jackrabbit Embedded Repository bundle.
Credits
-This description is based on Tony Giaccone's description Swapping Postgres for Derby sent to the Sling Users mailing list.
+This description is based on Tony Giaccone's description Swapping Postgres for Derby sent to the Sling Users mailing list.