Modified: sling/site/trunk/content/documentation/the-sling-engine/dispatching-requests.mdtext URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/the-sling-engine/dispatching-requests.mdtext?rev=1345726&r1=1345725&r2=1345726&view=diff ============================================================================== --- sling/site/trunk/content/documentation/the-sling-engine/dispatching-requests.mdtext (original) +++ sling/site/trunk/content/documentation/the-sling-engine/dispatching-requests.mdtext Sun Jun 3 17:57:55 2012 @@ -92,29 +92,16 @@ Note that these steps are processed for When servlet or script is called as a result of `RequestDispatcher.include` the following request attributes are set: -| Attribute Name -Attribute Type | Description | -| `org.apache.sling.api.include.servlet` -`javax.servlet.Servlet` | The name of the request attribute containing the `Servlet` which included the servlet currently being active. | -| `org.apache.sling.api.include.resource` -`org.apache.sling.api.resource.Resource` | The name of the request attribute containing the `Resource` underlying the `Servlet` which included the servlet currently being active. | -| `org.apache.sling.api.include.request*path*info` -`org.apache.sling.api.request.RequestPathInfo` | The name of the request attribute containing the `RequestPathInfo` underlying the `Servlet` which included the servlet currently being active | -| `javax.servlet.include.request_uri` -`String` | The name of the request attribute containing the `HttpServletRequest.getRequestURI()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active. -*Note:* In Sling, the `HttpServletRequest.getRequestURI()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | -| `javax.servlet.include.context_path` -`String` | The name of the request attribute containing the `HttpServletRequest.getContextPath()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active. -*Note:* In Sling, the `HttpServletRequest.getContextPath()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | -| `javax.servlet.include.servlet_path` -`String` | The name of the request attribute containing the `HttpServletRequest.getServletPath()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active. -*Note:* In Sling, the `HttpServletRequest.getServletPath()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | -| `javax.servlet.include.path_info` -`String` | The name of the request attribute containing the `HttpServletRequest.getPathInfo()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active. -*Note:* In Sling, the `HttpServletRequest.getPathInfo()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. -| `javax.servlet.include.query_string` -`String` | The name of the request attribute containing the `HttpServletRequest.getQueryString()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active. -*Note:* In Sling, the `HttpServletRequest.getQueryString()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | +| Attribute Name | Attribute Type | Description | +|-|-|-| +| `org.apache.sling.api.include.servlet`| `javax.servlet.Servlet` | The name of the request attribute containing the `Servlet` which included the servlet currently being active. | +| `org.apache.sling.api.include.resource`|`org.apache.sling.api.resource.Resource` | The name of the request attribute containing the `Resource` underlying the `Servlet` which included the servlet currently being active. | +| `org.apache.sling.api.include.request*path*info`|`org.apache.sling.api.request.RequestPathInfo` | The name of the request attribute containing the `RequestPathInfo` underlying the `Servlet` which included the servlet currently being active | +| `javax.servlet.include.request_uri`|`String` | The name of the request attribute containing the `HttpServletRequest.getRequestURI()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active.<br>*Note:* In Sling, the `HttpServletRequest.getRequestURI()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | +| `javax.servlet.include.context_path`|`String` | The name of the request attribute containing the `HttpServletRequest.getContextPath()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active.<br>*Note:* In Sling, the `HttpServletRequest.getContextPath()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | +| `javax.servlet.include.servlet_path`|`String` | The name of the request attribute containing the `HttpServletRequest.getServletPath()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active.<br>*Note:* In Sling, the `HttpServletRequest.getServletPath()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | +| `javax.servlet.include.path_info`|`String` | The name of the request attribute containing the `HttpServletRequest.getPathInfo()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active.<br>*Note:* In Sling, the `HttpServletRequest.getPathInfo()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. +| `javax.servlet.include.query_string`|`String` | The name of the request attribute containing the `HttpServletRequest.getQueryString()` of the request which included the servlet currently being active underlying the `Servlet` which included the servlet currently being active.<br>*Note:* In Sling, the `HttpServletRequest.getQueryString()` method will always return the same result regardless of whether it is called from the client request processing servlet or script or from an included servlet or script. This request attribute is set for compatibility with the Servlet API specification. | Constants are defined in the `org.apache.sling.api.SlingConstants` class for these request attributes.
Modified: sling/site/trunk/content/documentation/the-sling-engine/request-parameters.mdtext URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/the-sling-engine/request-parameters.mdtext?rev=1345726&r1=1345725&r2=1345726&view=diff ============================================================================== --- sling/site/trunk/content/documentation/the-sling-engine/request-parameters.mdtext (original) +++ sling/site/trunk/content/documentation/the-sling-engine/request-parameters.mdtext Sun Jun 3 17:57:55 2012 @@ -6,6 +6,8 @@ Excerpt: Explains how Sling provides req The Servlet API specification provides the following methods to access the parameters of a request +| Method | Description | +|-|-| | `HttpServletRequest.getQueryString()` | Returns the query part of the request URL | | `ServletRequest.getParameter(String)` | Returns the (first) named parameter | | `ServletRequest.getParameterValues(String)` | Returns all parameters of that name | @@ -19,12 +21,16 @@ As a special restriction only two kinds To overcome these restrictions and to provide uniform access to request parameters the Sling API in addition to the Servlet API methods to access parameters provides an abstraction of parameters which is applicable to all parameters sent by clients, the `RequestParameter` interface. Through this interface, each parameter may be analyzed for these topics: +| Type | Description | +|-|-| | Raw Content | Byte array and `InputStream` representation of the request parameter values. You will generally use the `InputStream` to handle uploaded files. | | String Content | Access the values as strings is some given encoding (see below) or by requesting the conversion using an explicit encoding. | | File Uploads | Find out whether a parameter is a file upload, get the size in bytes of the parameter value and client side file name as sent by the browser. | To accomodate this new interface as well as to provide easy access in the traditional way the `SlingHttpServletRequest` interface adds following methods to the standard Servlet API parameter access methods: +| Method | Description | +|-|-| | `getRequestParameter(String)` | Returns the (first) named parameter as a `RequestParameter` instance | | `getRequestParameters(String)` | Returns the named parameter as an array of `RequestParameter` instances | | `getRequestParameterMap()` | Returns `RequestParameterMap` being a map of `RequestParameter` arrays indexed by parameter names | Added: sling/site/trunk/content/documentation/the-sling-engine/url-to-script-resolution.mdtext URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/the-sling-engine/url-to-script-resolution.mdtext?rev=1345726&view=auto ============================================================================== --- sling/site/trunk/content/documentation/the-sling-engine/url-to-script-resolution.mdtext (added) +++ sling/site/trunk/content/documentation/the-sling-engine/url-to-script-resolution.mdtext Sun Jun 3 17:57:55 2012 @@ -0,0 +1,98 @@ +Title: URL to Script Resolution + +{info:title=More information} +This page is currently a copy from [this mailing list thread](http://markmail.org/message/tksvk4xfwapdpkwo). See also [SLING-387|https://issues.apache.org/jira/browse/SLING-387] and the unit test [ScriptSelectionTest.java](http://svn.apache.org/repos/asf/incubator/sling/trunk/servlets/resolver/src/test/java/org/apache/sling/servlets/resolver/helper/ScriptSelectionTest.java). +{info} + +[TOC] + +This page explains how Sling maps URLs to a script or and servlet. First of all Sling looks up the resource identified by the URL - typically a path inside the JCR repository, which is annotated by the `sling:resourceType` property which defines the resource type of that resource. Using this resource type (which is kind of a relative path, eg. "myblog/comment"), scripts or servlets are looked up. + +Scripts and servlets are itself resource in Sling and thus have a resource path: this is either the location in the JCR repository, the resource type in a servlet component configuration or the "virtual" bundle resource path (if a script is provided inside a bundle without being installed into the JCR repository). + +TODO: explain super types, servlet path mappings, node type resource types (`my:type -> my/type`) + + +## Fundamental: Scripts and Servlets are equal + +In the following discussion, I will write about scripts. This will always include servlets as well. In fact, internally, Sling only handles with Servlets, whereas scripts are packed inside a Servlet wrapping and representing the script. + +## Base: Resource Type Inheritance + +While not exactly part of our discussion, resource type inheritance as implemented for [SLING-278](https://issues.apache.org/jira/browse/SLING-278) plays a vital role in script resolution. + +Each resource type may have a resource super type, which may be defined in various ways. One example is having a `sling:resourceSuperType` property in the node addressed by the resource type. See [http://www.mail-archive.com/[email protected]/msg02365.html](http://www.mail-archive.com/[email protected]/msg02365.html) and [SLING-278](http://issues.apache.org/jira/browse/SLING-278) for more details. + +If a resource type has no explicit resource super type, the resource super type is assumed to be "sling/servlet/default". That is the resource type used for default script selection is also acting as a basic resource type much like java.lang.Object does for other types in the Java language. + +## Script Locations + +Scripts are looked up in a series of locations defined by the ResourceResolver.getSearchPath() and the resource type (and resource super types) of the requested resource: + + {scriptPathPrefix}/{resourceTypePath} + +The pseudo code for iterating the locations would be something like: + + + var type = resource.getResourceType(); + while (type != null) { + for (String root: resourceResolver.getSearchPath()) { + String path = root + type.toPath(); + findScriptsIn(path); + } + + if (type == defaultServlet) { + type = null; + } else { + type = getResourceSuperType(type); + if (type == null) { + type = defaultServlet; + } + } + } + + +## All requests are NOT equal + +GET and HEAD request methods are treated differently than the other request methods. Only for GET and HEAD requests will the request selectors and extension be considered for script selection. For other requests the servlet or script name (without the script extension) must exactly match the request method. + +That is for a PUT request, the script must be PUT.esp or PUT.jsp. For a GET request with a request extension of html, the script name may be html.esp or GET.esp. + +## Scripts for GET requests + +Apart for supporting scripts named after the request method, scripts handling GET and HEAD requests may be named differently for Sling to support a more elaborate processing order. + +Depending on whether request selectors are considered, a script may have two forms: + +* a. Ignoring request selectors (e.g. there are none in the request URI) `{resourceTypeLabel}.{requestExtension}.{scriptExtension}` +* b. Handling request selectors `{selectorStringPath}.{requestExtension}.{scriptExtension}` + +The constituents of these script names are as follows: + +* `{resourceTypeLabel}` - The last path segment of the path created from the resource type. This part is optional if the `{requestExtension}` is used in the script name. +* `{requestExtension}` - The request extension. This part may be ommitted if the request extension is "html", otherwise this part is required. If this part is ommitted, the `{resourceTypeLabel}` is required in the case of ignoring the selectors. +* `{scriptExtension}` - The extension, e.g. "esp" or "jsp", identifying the scripting langauage used. +* `{selectorStringPath}` - The selector string converted to a path, along the lines of `selectorString.replace('.', '/')`. + +## Priority + +The rules for script path priorization is defined as follows: + +* The more request selectors are matched, the better +* A script including the request extension matches better than one without a request extension (for html only) +* A script found earlier matches better than a script found later in the processing order. This means, that script closer to the original resource type in the resource type hierarchy is considered earlier. + +## Examples + +Taking up again the list of potential script paths for a request of a resource whose resource type is sling:sample and the request selectors are "print.a4" and the request extension is "html" could be: + +* (0) GET.esp +* (1) sample.esp +* (2) html.esp +* (3) print.esp +* (4) print/a4.esp +* (5) print.html.esp +* (6) print/a4.html.esp + +The priority of script selection would (6) - (4) - (5) - (3) - (2) - (1) - (0). Note that (4) is a better match than (5) because it matches more selectors even though (5) has an extension match where (4) does not. + Modified: sling/site/trunk/content/documentation/tutorials-how-tos/46-line-blog.mdtext URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/tutorials-how-tos/46-line-blog.mdtext?rev=1345726&r1=1345725&r2=1345726&view=diff ============================================================================== --- sling/site/trunk/content/documentation/tutorials-how-tos/46-line-blog.mdtext (original) +++ sling/site/trunk/content/documentation/tutorials-how-tos/46-line-blog.mdtext Sun Jun 3 17:57:55 2012 @@ -1,69 +1,71 @@ Title: 46 Line Blog -This tutorial is based on the first *Sling Gems* on dev.day.com: The [Sling gems: a blog in 46 lines of code]({{ refs.http://dev.day.com/microsling/content/blogs/main/sling-46-lines-blog.html.path }}). 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](http://dev.day.com/microsling/content/blogs/main/sling-46-lines-blog.html). 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]({{ refs.rapid-jcr-applications-development-with-sling.path }}) 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](http://www.slideshare.net/bdelacretaz/rapid-jcr-applications-development-with-sling-1196003) 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. ## Audience -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]({{ refs.slingxsite-discover-sling-in-15-minutes.path }}) 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]({{ refs.discover-sling-in-15-minutes.path }}) might be a better choice. ## Step 0: Start, configure and login to Sling -See [SLINGxSITE:Getting and Building Sling]({{ refs.slingxsite-getting-and-building-sling.path }}) 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]({{ refs.http://localhost:8888/system/console/bundles.path }}), 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*. +See [Getting and Building Sling]({{ refs.getting-and-building-sling.path }}) 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](http://localhost:8888/system/console/bundles), 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**. +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**. ## 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: -{code:html} -<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> + <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 {{/apps/blog/blog.esp}} {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 {{http://localhost:8888/content/blog/*.html}} {footnote} This assumes 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. +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). - 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. +To test the form, start Sling and save the above script as {{/apps/blog/blog.esp}} [^esp] in the Sling repository - a WebDAV mount is the easiest way to do that. Browsing to <http://localhost:8888/content/blog/*.html> [^port] should display the above form. + +[^esp]: ESP is Sling's server-side javascript language +[^port]: This assumes your instance of Sling is running on port 8888. If that's not the case, adjust the example URLs accordingly. + +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} +{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. +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? +## 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: +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: - {code:javascript} { "jcr:primaryType": "nt:unstructured", "text": "This is the foo text", @@ -75,15 +77,13 @@ That's reassuring, but what we really wa 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} -<head> - <script src="/system/sling.js"></script> -</head> + <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: +And add the `Sling.wizard()` after the form, where we had the _code of step 2 comes here_ comment: - {code:html} <!-- code of step 2 comes here --> <script>Sling.wizard();</script> @@ -98,40 +98,38 @@ The *sling.js* library provides utilitie Add the following code to your script, after the `Sling.wizard()` call that was added in step 2: -{code:html} -<h3>Navigation</h3> -<ul> - <li><em><a href="/content/blog/*.html">[Create new post]({{ refs.create-new-post.path }})</a></em></li> - <script> - var posts = Sling.getContent("/content/blog", 2); - for(var i in posts) { - document.write("<li>" - + "<a href='/content/blog/" + i + ".html'>" - + posts[i]({{ refs.i.path }}).title - + "</a></li>"); - } - </script> -</ul> - + <h3>Navigation</h3> + <ul> + <li><em><a href="/content/blog/*.html">[Create new post]({{ refs.create-new-post.path }})</a></em></li> + <script> + var posts = Sling.getContent("/content/blog", 2); + for(var i in posts) { + document.write("<li>" + + "<a href='/content/blog/" + i + ".html'>" + + posts[i]({{ refs.i.path }}).title + + "</a></li>"); + } + </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 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. +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. +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. +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 +## Step 4: Data first, structure later - You might have heard this mantra, which we apply in many areas of Sling. +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. +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: +Adding this inside our script's `<form>` element, for example: - {code:html} <br/>Author:<br/> <input type="author" name="author" style="width:100%"/> @@ -150,8 +148,7 @@ To keep things simple, we'll refrain fro ## That's the power of Sling -The 46-line blog is a good example of the power of Sling. It leverages the [SlingPostServlet]({{ refs.slingxsite-manipulating-content-the-slingpostservlet-servlets-post-slingpostservlet.path }}), 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]({{ refs.manipulating-content-the-slingpostservlet-servlets-post.path }}), 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. ----- ///Footnotes Go Here/// Modified: sling/site/trunk/content/documentation/tutorials-how-tos/jackrabbit-persistence.mdtext URL: http://svn.apache.org/viewvc/sling/site/trunk/content/documentation/tutorials-how-tos/jackrabbit-persistence.mdtext?rev=1345726&r1=1345725&r2=1345726&view=diff ============================================================================== --- sling/site/trunk/content/documentation/tutorials-how-tos/jackrabbit-persistence.mdtext (original) +++ sling/site/trunk/content/documentation/tutorials-how-tos/jackrabbit-persistence.mdtext Sun Jun 3 17:57:55 2012 @@ -1,7 +1,5 @@ Title: 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. This page is based on the journey of Tony Giaccone to get Sling running with a PostgreSQL based Jackrabbit instance. @@ -20,9 +18,9 @@ When you are not using the Derby persist ## 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/. +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/](http://www.springsource.com/repository/). -Another option is to create the bundle on your own using Peter Kriens' [BND Tool]({{ refs.http://www.aqute.biz/Code/Bnd.path }}): +Another option is to create the bundle on your own using Peter Kriens' [BND Tool](http://www.aqute.biz/Code/Bnd): 1. Get the JDBC driver for your database from the driver provider 1. Wrap the JDBC driver library into an OSGi bundle: @@ -33,8 +31,8 @@ Another option is to create the bundle o 1. 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.jar Tony reports no success with the Spring Source bundle, whily the BND approach worked for the PostgreSQL JDBC driver. @@ -46,7 +44,7 @@ To replace Derby in a running Sling inst 1. Uninstall the Apache Derby bundle 1. Install the JDBC bundle prepared in the first step -1. Stop the Jackrabbit Embedded Repository bundle\ +1. 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. 1. Refresh the packages (click the *Refresh Packages* button) @@ -57,7 +55,7 @@ Alternatively, you may wish to stop Slin 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 the `sling/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]({{ refs.http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/repository.xml.path }})` 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`](http://svn.apache.org/repos/asf/sling/trunk/bundles/jcr/jackrabbit-server/src/main/resources/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. @@ -105,4 +103,4 @@ Finally either start Sling or start the ## Credits -This description is based on Tony Giaccone's description [Swapping Postgres for Derby]({{ refs.http://markmail.org/message/wlbfrukmjjsl33hh.path }}) sent to the Sling Users mailing list. \ No newline at end of file +This description is based on Tony Giaccone's description [Swapping Postgres for Derby](http://markmail.org/message/wlbfrukmjjsl33hh) sent to the Sling Users mailing list. \ No newline at end of file
