invoke a script directly by its url

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

invoke a script directly by its url

Edgar Poce
Hi,

 I was wondering if there's any way to invoke scripts directly by a
url, a script which is not used as a template for another content.
A simple use case that comes to my mind is a simple CRUD page to
administer users. I'd like to invoke the script directly because it
won't be reused, it would be a different use case than the one
detailed in "sling in 15 minutes" page.
.e.g.
- the page can be located at at /admin/users.esp
- and the users could be stored under the page node, e.g
/admin/users.esp/sling:content/john.doe

is there any way to achieve this with sling?, if not what would be the
recommended practice to create simple crud pages?

sorry if the question is stupid, I'm trying to understand the best
practices and see the possibilities the sling platform offers to ease
the development.

Thanks in advance,
Edgar

Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Felix Meschberger-2
Hi Edgar,

Pleased to see you here in Sling ;-)


Am Dienstag, den 18.03.2008, 13:49 -0300 schrieb Edgar Poce:

> Hi,
>
>  I was wondering if there's any way to invoke scripts directly by a
> url, a script which is not used as a template for another content.
> A simple use case that comes to my mind is a simple CRUD page to
> administer users. I'd like to invoke the script directly because it
> won't be reused, it would be a different use case than the one
> detailed in "sling in 15 minutes" page.
> .e.g.
> - the page can be located at at /admin/users.esp
> - and the users could be stored under the page node, e.g
> /admin/users.esp/sling:content/john.doe

I would probably not store the users below the script, but for example
under /users or even /system/users...

>
> is there any way to achieve this with sling?, if not what would be the
> recommended practice to create simple crud pages?

Not at the moment. We once had this support, but there was quite some
controversy around this feature. I for my part like it.

The problem is, that we could not really find a good way of deciding
whether to execute a requested resource or not. IIRC the main issue was
a collision of the script extension used for JavaScript: We used .js at
that time for both client- and server-side. The problem here is, that
server-side JavaScript should be executed but client-side must not ...

In the meantime we changed the extension for server-side JavaScript
to .ecma, so this collision is not a big issue any more.

What you could of course do as a workaround is to set the
sling:resourceType property of your crud page to the page itself. That
is the /admin/users.esp/sling:resourceType property would
be /admin/users.esp.

This would result in resolving the script for /admin/users.esp to be the
resource itself and there you are.

If the node type of /admin/users.esp does not allow setting the
sling:resourceType property, you might want to add the sling:Resource
mixin node type to the /admin/users.esp node.

>
> sorry if the question is stupid, I'm trying to understand the best
> practices and see the possibilities the sling platform offers to ease
> the development.

This question is not stupid but up for debate ;-) As I said, I
personally like directly addressing scripts for execution. But up to
now, we could not find a good and simple algorithm to decide on a
request-by-request basis, whether to execute the addressed script or
not.

Regards
Felix



Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Edgar Poce
Hi,

On Tue, Mar 18, 2008 at 6:29 PM, Felix Meschberger <[hidden email]> wrote:

>  > is there any way to achieve this with sling?, if not what would be the
>  > recommended practice to create simple crud pages?
>
>  What you could of course do as a workaround is to set the
>  sling:resourceType property of your crud page to the page itself. That
>  is the /admin/users.esp/sling:resourceType property would
>  be /admin/users.esp.
>
>  This would result in resolving the script for /admin/users.esp to be the
>  resource itself and there you are.
>
>  If the node type of /admin/users.esp does not allow setting the
>  sling:resourceType property, you might want to add the sling:Resource
>  mixin node type to the /admin/users.esp node.
>

I see I joined the discussion late :), I've just read LOTS of mails
about direct execution and I see why this feature was removed, I
surely missed lots of things though so bear with me :).

IMHO if the target developer is not a senior java developer, who is
used to weird indirections from almost every framework, then a mixin,
the proposed workaround or a complex algorithm should be avoided.
IMHO, the tooling to work with Sling for a newbie should be the
explorer and a text editor. In any case, if scripts should not be
executed by default then the less intrusive option seems to be using a
selector because it doesn't involve dealing with low level JCR calls
(adding properties, nodes or mixins).

A single step to deploy an script (copying a file) is what any other
scripting environment such as PHP in Apache offers, IMHO it's not good
to make Sling less productive than other alternatives. IMHO no curl
nor eclipse are good for newcomers, I'm thinking about the knowledge
and tooling needed to start being productive, a low entry barrier
helps to add productive people to a dev team rapidly if needed.

IMHO the indirections needed to use scripts as templates are needed
but only for more advanced use cases. It would be cool if Sling in 15
minutes were the second hop, the first hop would be preparing an
script with notepad and copying it to sling with drag and drop from
windows explorer in 5' or less.

just my 2 cents :)

br,
edgar

>
>  >
>  > sorry if the question is stupid, I'm trying to understand the best
>  > practices and see the possibilities the sling platform offers to ease
>  > the development.
>
>  This question is not stupid but up for debate ;-) As I said, I
>  personally like directly addressing scripts for execution. But up to
>  now, we could not find a good and simple algorithm to decide on a
>  request-by-request basis, whether to execute the addressed script or
>  not.
>
>  Regards
>  Felix
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Alexander Klimetschek
Hi Edgar!

Am 19.03.2008 um 12:34 schrieb Edgar Poce:

> IMHO the indirections needed to use scripts as templates are needed
> but only for more advanced use cases. It would be cool if Sling in 15
> minutes were the second hop, the first hop would be preparing an
> script with notepad and copying it to sling with drag and drop from
> windows explorer in 5' or less.

I agree that speeding up new developers to get into Sling is  
important. But this touches a central concept of Sling: Sling  
implements a fully REST-oriented server and thus features a new  
concept in web application frameworks: first is the resource (JCR  
node), second the representation (script generating HTML).

For the most parts, nodes in the JCR are your resource (Sling also  
allows other things than JCR to be resources, but this is an advanced  
feature). These nodes are directly mapped from the URL. Then a script  
just accesses this node (currentNode) and renders some HTML around it.  
Other scripts (aggregating scripts) might need to access multiple  
resources (eg. navigation, sidebar, footer, elements of a list) and do  
so by including the *resource*, ie. via sling.include("/path/to/
resource").

The basic principle is
- not to specify what data entities to access in your scripts (what an  
SQL statement in a PHP script would do)
- but to specify which script renders a certain entity (by setting the  
sling:resourceType property in the JCR node).

You can work around it as you can use sling.include() with arbitrary  
paths, access the full JCR API and use the APIs of whatever OSGi  
bundles are present in your Sling server. But it doesn't follow the  
main Sling architecture style.

The advantages are
1) being very RESTful (resources and representations modelled  
correctly inside the server)
2) removing one or two data models (previously: URL structure,  
business objects, DB schema; now: URL = resource = JCR structure)
3) and having very reusable scripts.

These are apparent in applications with lots of different content  
elements or when you need easy customizable pages (think CMS).

It requires some rethinking, though. Maybe that principle should be  
clearly documented ;-)

Regards,
Alex

PS: I hope I got that concept right myself... If I am wrong, please  
correct me!

--
Alexander Klimetschek
[hidden email]





Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Edgar Poce
On Wed, Mar 19, 2008 at 9:39 AM, Alexander Klimetschek <[hidden email]> wrote:

> Hi Edgar!
>
>  Am 19.03.2008 um 12:34 schrieb Edgar Poce:
>
>
>  > IMHO the indirections needed to use scripts as templates are needed
>  > but only for more advanced use cases. It would be cool if Sling in 15
>  > minutes were the second hop, the first hop would be preparing an
>  > script with notepad and copying it to sling with drag and drop from
>  > windows explorer in 5' or less.
>
>  I agree that speeding up new developers to get into Sling is
>  important. But this touches a central concept of Sling: Sling
>  implements a fully REST-oriented server and thus features a new
>  concept in web application frameworks: first is the resource (JCR
>  node), second the representation (script generating HTML).
>

I'm surely missing something, I don't see why running a script
directly would break REST principles. The script itself is the
resource and if the user invokes it with a custom selector the
representation would be the result of the execution of the given
script.

>
>  The basic principle is
>  - not to specify what data entities to access in your scripts (what an
>  SQL statement in a PHP script would do)

That's why I expected sling to run the script and I planned to store
the contents under the current node, in my previous example  I would
have expected "/[thescript]/sling:content" to be the current node
because "jcr:content" would be already occupied by the script itself.
In the simplest usage scenario a single script would be a self
contained application.

Maybe I'm missing important stuff, my usage of sling would be:
1. use directly executed scripts for simple stuff
2. use the template indirection later, only if needed
3. integrate a web framework for complex use cases (wicket would be my choice)

>  It requires some rethinking, though. Maybe that principle should be
>  clearly documented ;-)
>

:), maybe some comments about best practices which differ from other
scripting environments would help.

thanks,
Edgar

>  Regards,
>  Alex
>
>  PS: I hope I got that concept right myself... If I am wrong, please
>  correct me!
>
>  --
>  Alexander Klimetschek
>  [hidden email]
>
>
>
>
>

Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Alexander Klimetschek
Am 19.03.2008 um 14:28 schrieb Edgar Poce:
> I'm surely missing something, I don't see why running a script
> directly would break REST principles. The script itself is the
> resource and if the user invokes it with a custom selector the
> representation would be the result of the execution of the given
> script.

You'd break the strict concept of a REST server as you mix resources  
and representations. If you directly call the representation (the  
script), you hide the resource inside your script, and the framework  
(Sling) no longer knows about it. You will loose certain features (eg.  
automatic handling of other http methods than GET, ie. POST, PUT,  
DELETE which are handled with a sling default implementation or a  
POST.js script in your sling:resourceType location). And your code  
architecture no longer will be as clean and helpful for large-scale  
development as it could be.


> 3. integrate a web framework for complex use cases (wicket would be  
> my choice)

FYI, Sling has its own js client library [1] (previously called r-jax,  
then ujax, don't know exactly about the current status as it was  
renamed recently, anyone?) that simplifies access to nodes and  
properties in client side javascript as well as modifying them.

[1] https://issues.apache.org/jira/browse/SLING-326

And there was some work for Dojo recently, providing a bundle that  
provides the Dojo files [1], a Dojo store implementation that connects  
to Sling [3] and finally a web-based IDE for Dojo/Sling development  
called Bunkai [4].

[2] https://issues.apache.org/jira/browse/SLING-302
[3] https://issues.apache.org/jira/browse/SLING-301
[4] https://issues.apache.org/jira/browse/SLING-261


> :), maybe some comments about best practices which differ from other
> scripting environments would help.

Very rough stuff can be found on the wiki: http://cwiki.apache.org/SLING/introductions.html


Regards,
Alex

--
Alexander Klimetschek
[hidden email]





Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Edgar Poce
Hi Alexander,

 thank you very much for you explanations, I've got on more question.
Since you are provinding scripting alternatives to my comment of using
wicket I guess usage of strongly typed OO languages such as java to
build applications on top of Sling is discouraged, large scale
applications are supposed to be written only in scripting languages?

thanks again,
Edgar

Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Padraic Hannon
In reply to this post by Alexander Klimetschek
Sorry to jump in so late, but this conversation is one that I had
struggled with as well. After spending a little time speaking with
Tobias I finally got it straight. Alexander is right, this does take a
bit of a mental switch. For example, in lets look at a blog index page:

/blog/january.html (as a rough example)

The january node in jcr contains child nodes which are entries. The
default script associated with the january node loops over its children
and includes them:

/blog/january/post1.list.html
/blog/january/post2.list.html
....

The way I would write this have normally wrote the january default
script would render all the html, link to the children, etc. However,
there is another way to do this, by including the post1.list.html we
would invoke the list script for a post and it would render the data
appropriately. Thus, the content url resolves the rendering script. So
that different representations of the node are possible
post1.intro.html, post1.body.html, etc where each selector helps resolve
a different rendering capability.

I still struggle with this a bit as it is very different from what I am
used to, also I have been spending too much time on our back end data
problems here at Edmunds, so I haven't been able to focus on sling as
much which has not helped in furthering my contributions. I hope I am
echoing my conversation with Tobias correctly and understood him. I
share some of Edgar's concerns especially given I have so many different
representations of the same data to work on which leads me to want to
just address components and pass into them the data I want them to
render ie /blog/index.january.html (or something). Sling turns this
around and goes content first and not code first which for the web has a
certain elegance.

-paddy


Alexander Klimetschek wrote:

> Hi Edgar!
>
> Am 19.03.2008 um 12:34 schrieb Edgar Poce:
>
>> IMHO the indirections needed to use scripts as templates are needed
>> but only for more advanced use cases. It would be cool if Sling in 15
>> minutes were the second hop, the first hop would be preparing an
>> script with notepad and copying it to sling with drag and drop from
>> windows explorer in 5' or less.
>
> I agree that speeding up new developers to get into Sling is
> important. But this touches a central concept of Sling: Sling
> implements a fully REST-oriented server and thus features a new
> concept in web application frameworks: first is the resource (JCR
> node), second the representation (script generating HTML).
>
> For the most parts, nodes in the JCR are your resource (Sling also
> allows other things than JCR to be resources, but this is an advanced
> feature). These nodes are directly mapped from the URL. Then a script
> just accesses this node (currentNode) and renders some HTML around it.
> Other scripts (aggregating scripts) might need to access multiple
> resources (eg. navigation, sidebar, footer, elements of a list) and do
> so by including the *resource*, ie. via
> sling.include("/path/to/resource").
>
> The basic principle is
> - not to specify what data entities to access in your scripts (what an
> SQL statement in a PHP script would do)
> - but to specify which script renders a certain entity (by setting the
> sling:resourceType property in the JCR node).
>
> You can work around it as you can use sling.include() with arbitrary
> paths, access the full JCR API and use the APIs of whatever OSGi
> bundles are present in your Sling server. But it doesn't follow the
> main Sling architecture style.
>
> The advantages are
> 1) being very RESTful (resources and representations modelled
> correctly inside the server)
> 2) removing one or two data models (previously: URL structure,
> business objects, DB schema; now: URL = resource = JCR structure)
> 3) and having very reusable scripts.
>
> These are apparent in applications with lots of different content
> elements or when you need easy customizable pages (think CMS).
>
> It requires some rethinking, though. Maybe that principle should be
> clearly documented ;-)
>
> Regards,
> Alex
>
> PS: I hope I got that concept right myself... If I am wrong, please
> correct me!
>
> --
> Alexander Klimetschek
> [hidden email]
>
>
>


Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Jukka Zitting-3
In reply to this post by Alexander Klimetschek
Hi,

On Wed, Mar 19, 2008 at 3:51 PM, Alexander Klimetschek <[hidden email]> wrote:

> Am 19.03.2008 um 14:28 schrieb Edgar Poce:
> > I'm surely missing something, I don't see why running a script
>  > directly would break REST principles. The script itself is the
>  > resource and if the user invokes it with a custom selector the
>  > representation would be the result of the execution of the given
>  > script.
>
>  You'd break the strict concept of a REST server as you mix resources
>  and representations. If you directly call the representation (the
>  script), you hide the resource inside your script, and the framework
>  (Sling) no longer knows about it.

There is nothing in REST that prevents a resource from being dynamic.

For example "latest blog entries" is a perfectly fine resource, which
can be represented in various ways. The fact that the "latest blog
entries" resource is not a static entry in the content repository is
of no concern, it can just as well be a script that looks through the
blog archive for the latest entries.

Of course you can also expose the "latest blog entries script"
resource based on the static script entry in the repository, and doing
that is certainly a good idea in light of WebDAV editing, etc.

The important thing is to realize that those are two separate
resources that should be identified and accessed through separate
URIs.

BR,

Jukka Zitting

Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Carsten Ziegeler
In reply to this post by Edgar Poce
Hi,

Edgar Poce wrote:
> Hi Alexander,
>
>  thank you very much for you explanations, I've got on more question.
> Since you are provinding scripting alternatives to my comment of using
> wicket I guess usage of strongly typed OO languages such as java to
> build applications on top of Sling is discouraged, large scale
> applications are supposed to be written only in scripting languages?
>
:) No, definitly not - I think the choice of language is independent
from the size or load of your application. Instead of writing a script
you can implement a servlet which you can btw invoke directly) or use
jsp (ok, it's kind of a scripting language as well).

I would rather put Sling as "web framework" without the "application".
There are so many different "application" frameworks out there and it
would be great to see some kind of an integration between some of them
and Sling.

As mentioned in this thread, Sling's approach is different to most other
frameworks, and we definitly don't want to provide a full-blown "web
application" framework.

Carsten
--
Carsten Ziegeler
[hidden email]

Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Alexander Klimetschek
In reply to this post by Edgar Poce
Am 19.03.2008 um 15:09 schrieb Edgar Poce:

> Since you are provinding scripting alternatives to my comment of using
> wicket I guess usage of strongly typed OO languages such as java to
> build applications on top of Sling is discouraged, large scale
> applications are supposed to be written only in scripting languages?

No, not at all. Sling is built to provide first-class support for both  
scripting and Java.

For scripting the main focus currently lies on server-side Javascript  
with esp templates, but all JSR-223 scripting languages are possible.  
They just need special default objects and methods that fit better in  
the language (eg. simplification of JCR API through node.mychild in  
Javascript compared to node.getChild("mychild") in plain Java).  
Scripting is good for the start.

And for Java the usage of OSGi bundles gives you an excellent software  
lifecycle managament, because bundles are versioned, can be installed  
at runtime and the OSGi system can check if a bundle fits with the  
rest of the bundles. Bundles have to explicitly export public packages  
as APIs, usage of private stuff is simply impossible. OSGi services  
are used to provide services, including the notion of start/stop  
bundle events (needed for runtime installation/deinstallation). This  
really helps once your app gets bigger.

Bundles can also include scripts if you want to manage them better.

Regards,
Alex

--
Alexander Klimetschek
[hidden email]





Reply | Threaded
Open this post in threaded view
|

Re: invoke a script directly by its url

Alexander Klimetschek
In reply to this post by Jukka Zitting-3

Am 19.03.2008 um 15:30 schrieb Jukka Zitting:

>> You'd break the strict concept of a REST server as you mix resources
>> and representations. If you directly call the representation (the
>> script), you hide the resource inside your script, and the framework
>> (Sling) no longer knows about it.
>
> There is nothing in REST that prevents a resource from being dynamic.

That's why I constrained it by saying "strict concept of a REST  
server". This is the personal view I have on Sling - it's of course  
possible to view and use Sling differently. Thank god it's very  
flexible.


> For example "latest blog entries" is a perfectly fine resource, which
> can be represented in various ways. The fact that the "latest blog
> entries" resource is not a static entry in the content repository is
> of no concern, it can just as well be a script that looks through the
> blog archive for the latest entries.

I would model the example "latest blog entries" not as a resource, but  
as a special representation of the blog entries resource: it could be  
denoted by an additional selector (/blog/entries.latest.html vs. /blog/
entries.html for all entries) or by a query paramter (/blog/
entries.html?show=latest&count=10).

Otherwiese, resources can be dynamic in Sling, although only on a  
layer on top of JCR. If you use JCR, the advantage is that you see  
your content = resource structure. IMHO this makes things much  
simpler, because you can explicitly model your content. For certain  
use cases this means that your JCR repository might get very big,  
because you make resources that used to be "virtual" in traditional  
systems explicit by storing them as nodes in the repo.


> Of course you can also expose the "latest blog entries script"
> resource based on the static script entry in the repository, and doing
> that is certainly a good idea in light of WebDAV editing, etc.
>
> The important thing is to realize that those are two separate
> resources that should be identified and accessed through separate
> URIs.

Yes. Having the scripts reside in a separate location from the content  
(eg. /apps/myapp) solves this easily.


Regards,
Alex

--
Alexander Klimetschek
[hidden email]