SHRT = Semi-Humorous Random Thought

Here's the deal: Cocoon is a very powerful publishing framework adapted to do web applications, and Ruby on Rails is a very empowering web application framework that can be adapted for a number of purposes. There are two very different mindsets behind the two frameworks--and I believe we can leverage the very potent lessons learned from Rails for the Cocoon framework. The only real humorous aspect of this post is the acronym I came up with above. In one summary statement:

CRACK: A highly adictive web framework that is very potent. Side affects include loss of weight, faster completion, and eagerness for more. Best selling point: seeing the reaction of saying your a "CRACK Ho".

In all seriousness, the biggest lesson from the Ruby on Rails project that Cocoon can learn is the power of convention. One of the biggest things that contributes to the high learning curve of Cocoon is the lack of convention. Because there are so many ways of doing things, the user has to learn all of them to determine what is going to be best for the project the user is working on. I belive that this lack of convention is even a bigger contributor than all the different XML standards that we integrate. A long time ago Stefano gave the RT on the URL as a contract--and rightly so. The Sitemap was born of that RT allowing Cocoon to respect the external contract and the developer to organize the filesystem any way they chose. The Rails solution to the problem is the convention of the MVC architecture is also mapped in a logical way to the files and class structure. Let me lay out the convention used:

Controller
----------
Rails has a definite mapping of the URL to a controller. The convention is {context}/{controller}/{action}[/{id}] where {context} is the location where the app is running, {controller} is the controller class that responds to actions, {action} is the method on the controller class that is called to process a request, and {id} is an optional piece that identifies a specific record. The controller class is defined in the app/controllers/ directory and has a naming convention of {name}Controller. For example a "Login" controller would be named "LoginController". Rails finds the controller based on the URL. Once Rails has the controller it calls the method matching the action. One of the side effects is that the URL does not have any extensions defined (i.e. there is no .html or .pdf in the URL). The job of the controller is to do any set up for the request before it allows the action to "fall through" to the matching view.

Model
-----
The Rails model is one of the most powerful aspects of the whole framework. I'm not going to go into the whole ActiveModel architecture other than to say that the model lives in the app/models/ directory and the class name is the singular form of the concept (i.e. LogEntry) and the backing database table is the plural form (i.e. LogEntries). Using convention to map class methods to tables and records is a very powerful aspect that beats out anything else in the Java world. It would be a project in and of itself to write a replacement for this piece--which is not something I would recommend for CRACK.

View
----
The Rails view lives in app/views/{controller}/{action}. That's right, there is a mapping of a set of views directly 1:1 to the controllers. In the case of the LoginController there would be an app/views/login/ directory, and for each action ("index", "login" etc.) there would be a view that corresponds. In the Ruby on Rails world these are .rhtml files so they are analogous to XSP or JXL files. In fact I would argue that it is closer to JXL than XSP. Once the method in the controller is complete, provided the controller did not explicitly send a named page, the view is selected from this directory. In the CRACK version matching the /login/index URL, we would look for (in this order) a .jx file, a .xml file, or a .xsp file that matches the name of the action "index". More clearly, in that example CRACK would look for app/views/login/index.jx first, and then substitute the other extensions in case they are there. The Rails view framework also allows fragments that can be embedded in other views, but this is good enough for now.

Now, imagine a Cocoon scenario where the user is faced with a blank project. Where to begin... Using the power of convention, they start writing a class named HelloController.java located in the app/controllers/ directory. They add one method called index() to the class. Then they open the browser to http://localhost:8000/cocoon/hello--at which point Cocoon compiles the HelloController.java class and responds by processing the index() method (oh yeah, forgot to mention the convention of the index method being the default for any controller). The user sees an error message saying that the view app/views/hello/index.jx could not be found. They realize, "Oh, that must be where we process the view". They add the index.jx file in the proper location and retry the URL. Success! Relieved and happy with the results they start adding more and more functionality until they have a wonderfully powerful application.

Where CRACK is Better
---------------------
Ruby on Rails is highly HTML centric. That's ok because 80% of all web applications are HTML centric. However, we can leverage a convention that they started in a more powerful way. In addition to the normal View conventions, Rails also has the concept of a layout. You can apply the same layout to all the views in your application. Now, remember that I said that Rails doesn't support extensions (.html, .png, etc.). We can set up a set of layouts that are essentially the finishing pipeline for the application. By specifying a generic page markup we can provide default layouts, but the convention would work like this:

* The layout has a base name such as "site" which is how the layout would be specified in the controller. * The XSLT layout naming convention would be {name}2{ext}.xsl, and we would automatically select the serializer mapped to the {ext} name. - Example: login/index.html using the "site" layout would transform the standard markup using the "site2html.xsl" file and use the "html" serializer. - This allows us to also render a "site2pdf.xsl" using the "pdf" serializer for /article/show/3.pdf

Changes to Cocoon
-----------------
In order to support something like this, we don't have to make fundamental changes to Cocoon. In fact, all we have to do is provide an alternate Sitemap implementation that uses reflection to find the controller class and build the pipeline based on the view source, the layout location, etc. One of the things that would also help _emensely_ is to automatically generate a 404 return response if there is no Controller/Action match. There are other things that will help in the process, but I believe this is a much more usable way to get baptised into Cocoon--and still leverage its power. Because we would be using convention to wire together an application, we have the power to even build in some normal conventions for being browser aware by default. If the end client's browser is smart enough to handle client side styling then we can let it happen--with no more effort required by the developer.

Oh, and one more thing: we default to UTF-8 as the default encoding all the way through. There are issues with the ESQL logicsheet introducing encoding errors, and a few more other locations. Just because much of the commercial industry seems to be ignoring internationalization does not mean we should follow they poor example.

What do you think? Rosy picture? BTW, I only used the name CRACK as an eye catcher--I'm not expecting the final product to be named that.

Reply via email to