kwin commented on a change in pull request #67:
URL: https://github.com/apache/sling-site/pull/67#discussion_r688569340



##########
File path: src/main/jbake/content/documentation/bundles/scripting.md
##########
@@ -67,9 +67,143 @@ Mapping `html` to Thymeleaf 3.0:
       "html=Thymeleaf:3.0"
     ]
 
+## Scripts are Servlets
+
+The Sling API defines a `SlingScript` interface which is used to represent 
(executable) scripts inside of Sling. This interface is implemented in the 
[Scripting Core bundle][8] in the `DefaultSlingScript` class which also 
implements the `javax.servlet.Servlet`.
+
+To further simplify the access to scripts from the Resource tree, the 
`scripting/core` bundle registers an `AdapterFactory` to adapt Resources to 
Scripts and Servlets (the `SlingScriptAdapterFactory`). In fact the adapter 
factory returns instances of the `DefaultSlingScript` class for both Scripts 
and Servlets.
+
+From the perspective of the [Servlet resolver][7], scripts and servlets are 
handled exactly the same. In fact, internally, Sling only deals with Servlets, 
whereas scripts are packed inside a Servlet wrapping and representing the 
script.
+
+## Resource Scripts
+
+Scripts are looked up in a series of resource resolver 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; 
+            } 
+        } 
+    } 
+
+### Resource script naming conventions
+
+Depending on whether request selectors are considered, a script may have two 
forms: 
+
+1. Ignoring request selectors (e.g. there are none in the request URI): 
`{resourceTypeLabel}.{requestExtension}.{requestMethod}.{scriptExtension}` 
+2. Handling request selectors: 
`{selectorStringPath}.{requestExtension}.{requestMethod}.{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. The resource type might either be set via the `sling:resourceType` 
property on the accessed node or if that property is not there its primary node 
type (property `jcr:primaryType`) is taken as fall-back.
+* `{requestExtension}` - The request extension. This part may be omitted if 
the request extension is `html`, otherwise this part is required. If this part 
is omitted, the `{resourceTypeLabel}` is required in the case of ignoring the 
selectors.
+* `{requestMethod}` - The request's HTTP method. This part may be omitted if 
the script is meant for a `GET` or a `HEAD` request. This part is required for 
any other HTTP method.
+* `{scriptExtension}` - The extension identifying the scripting language used. 
This part is mandatory. For more details about the available Script Engines and 
their registered extensions check the [Sling 
Scripting](/documentation/bundles/scripting.html) page.
+* `{selectorStringPath}` - The selector string converted to a path, along the 
lines of `selectorString.replace('.', '/')`. If less selectors are specified in 
the script name than given in the request, the script will only be taken into 
consideration if the given selectors are the **first** selectors in the 
request. This means *sel1/sel2.html.jsp* will be a candidate for the request 
url */content/test.sel1.sel2.sel3.html* but not for 
*/content/test.sel3.sel1.sel2.html*. So the order of selectors is relevant!
+
+
 ## Bundled Scripts
 
-Scripts may also be provided in OSGi bundles (precompiled or embedded) since 
[Sling Servlet Resolver 
2.7.0](https://github.com/apache/sling-org-apache-sling-servlets-resolver#bundled-scripts).
+Scripts may also be provided in OSGi bundles (precompiled or embedded) since 
[Sling Servlet Resolver 
2.7.0](https://github.com/apache/sling-org-apache-sling-servlets-resolver#bundled-scripts)
 through the org.apache.sling.servlets.resolver.bundle.tracker API in addition 
to classical Resource based scripts.
+
+Although traditionally scripts are deployed as content stored in the search 
paths of a Sling instance, this leaves very little
+room for script evolution in a backwards compatible way. Furthermore, 
versioning scripts is a difficult process if the only
+mechanism to do this is the `sling:resourceType` property, since consumers 
(content nodes or other resource types) have then to
+explicitly mention the version expected to be executed.
+
+Scripts should not be considered content, since their only purpose is to 
actually generate the rendering for a certain content
+structure. They are not consumed by users, but rather by the Sling Engine 
itself and have very little meaning outside this
+context. As such, scripts should be handled like code:
+
+  1. they _provide an HTTP API_;
+  2. they can evolve in a [_semantical_  way][1];
+  3. they have a _developer audience_.
+
+  
+### Technical Background
+
+Being built around a [`BundleTrackerCustomizer`][2], the 
`org.apache.sling.servlets.resolver.internal.bundle.BundledScriptTracker`
+monitors the instance's bundles wired to the 
`org.apache.sling.servlets.resolver` bundle and scans the ones providing a 
`sling.servlet`
+[capability][3]. The wiring is created by placing a `Require-Capability` 
header in the bundles that provide the `sling.servlet` capability:
+
+```
+osgi.extender;filter:="(&(osgi.extender=sling.scripting)(version>=1.0.0)(!(version>=2.0.0)))"
+```
+
+A `sling.servlet` capability has almost the same attributes as the properties 
required to [register a servlet on the Sling platform][4]:
+
+  1. `sling.servlet.resourceTypes:List` - mandatory; defines the provided 
resource type; its value is a list of resource types
+  2. `sling.servlet.selectors:List` - optional; defines the list of selectors 
that this resource type can handle;
+  3. `sling.servlet.extensions:List` - optional; defines the list of 
extensions that this resource type can handle;
+  4. `sling.servlet.methods:List` - optional; defines the list of HTTP methods 
that this resource type can handle;
+  5. `version:Version` - optional; defines the version of the provided 
`resourceType`;
+  6. `extends:String` - optional; defines which resource type it extends; the 
version range of the extended resource type is defined in a
+    `Require-Capability`.
+
+The `BundledScriptTracker` will register a Sling Servlet with the appropriate 
properties for each `sling.servlet` capability. The
+servlets will be registered using the bundle context of the bundle providing 
the `sling.servlet` capability, making
+sure to expose the different versions of a resource type as part of the 
registered servlet's properties. On top of this, a plain resource
+type bound servlet will also be registered, which will be automatically wired 
to the highest version of the `resourceType`. All the
+mentioned service registrations are managed automatically by the 
`BundledScriptTracker`.
+
+### So how do I deploy my scripts?
+Short answer: exactly like you deploy your code, preferably right next to it. 
Pack your scripts using the following conventions:
+
+  1. create a `src/main/resources/javax.script` folder in your bundle (if you 
want to embed the scripts as they are) or just put the
+   scripts in `src/main/scripts` if you want to precompiled them (e.g. JSP and 
HTL);
+  2. each folder under the above folders will identify a `resourceType`;
+  3. inside each `resourceType` folder you can optionally create a `Version` 
folder; this has to follow the Semantic Versioning
+   constraints described at [1];
+  4. add your scripts, using the same [naming conventions that you were used 
to from before][5];
+  5. manually define your provide and require capabilities; just kidding; add 
the
+  
[`scriptingbundle-maven-plugin`](https://github.com/apache/sling-scriptingbundle-maven-plugin)
 to your build section and add its required
+  properties in the `maven-bundle-plugin`'s instructions (check [these 
examples](https://github.com/apache/sling-org-apache-sling-scripting-bundle-tracker-it/tree/master/examples/));
+  6. `mvn clean sling:install`.
+
+### Integration Tests
+
+The integration tests for bundled scripts are provided by the 
[`org.apache.sling.scripting.bundle.tracker.it`](https://github.com/apache/sling-org-apache-sling-scripting-bundle-tracker-it)
 project.
+
+## Script resolution order
+
+The [same rules as for servlets][6] are being followed but in addition keep in 
mind that bundled scripts (as well as servlets) are prefered over resource 
scripts.

Review comment:
       @karlpauls Is this observation correct? I couldn't find according tests 
for that....




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


Reply via email to