Using Control Flow
The general flow of actions in an application which uses the control flow is as described below.
The request is received by Cocoon and passed to the sitemap for processing. In the sitemap, you can do two things to pass the control to the Control Flow layer:
- You can invoke a JavaScript top-level function to start processing a logically grouped sequences of pages. Each time a response page is being sent back to the client browser from this function, the processing of the JavaScript code stops at the point the page is sent back, and the HTTP request finishes. Through the magic of continuations, the execution state is saved in a continuation object. Each continuation is given a unique string id, which could be embedded in generated page, so that you can restart the saved computation later on.
- To invoke a top level JavaScript function in the Control Flow, you use the <map:call function="[function-name]"/> construction.
- To restart the computation of a previously stopped function, you use the <map:call continuation="..."/> construction. This restarts the computation saved in a continuation object identified by the string value of the continuation attribute. This value could be extracted in the sitemap from the requested URL, from a POST or GET parameter etc. When the computation stored in the continuation object is restarted, it appears as if nothing happened, all the local and global variables have exactly the same values as they had when the computation was stopped.
The second argument to cocoon.sendPageAndWait() and cocoon.sendPage() is a context object, which can be a simple dictionary with values that need to be displayed by the View. More generally any Java or JavaScript object can be passed here, as long as the necessary get methods for the important values are provided.
The page specified by the URL is processed by the sitemap, using the normal sitemap rules. The simplest case is a generator followed by an XSLT transformation and a serializer. This page generation is part of the View layer. To process a page you can make use of several Cocoon generators to retrieve values from the context objects passed by the Control Flow.
Going back to the cocoon.sendPageAndWait() and sendPage() functions, there is a big difference between them. The first function will send the response back to the client browser, and will stop the processing of the JavaScript script by saving it into a continuation object. The other function, cocoon.sendPage() will send the response, but it will not stop the computation. This is useful for example when you need to exit a top-level JavaScript function invoked with <map:call function="..."/>.
The above explains how MVC could be really achieved in Cocoon with the control flow layer. Note that there is no direct communication between Model and View, everything is directed by the Control Flow by passing to View a context object constructed from Model data.
As hinted in the previous section, an application using Cocoon's MVC approach is composed of three layers:
- A JavaScript controller which implements the interaction with the client
- The business logic model which implements your application
- The page templates, which describe the content of the pages, and XSLT stylesheets which describe the look of the content.
- login,
- registerUser,
- edit and
- logout.