[Maypole] The Future of Maypole

From: Sebastian Riedel (sri at oook.de)
Date: Sun Oct 31 2004 - 18:42:09 GMT


Hi,

Just to make sure, this is not bad news. :)

=== Introduction ===

You may know i'm a bit ill at the moment and have to stay at home, once
a day wandering to the doctor to get my daily injection... :(

Good thing is, that i had some time to rethink Maypole and what i'm now
about to show you is definately cool.

I guess people will hate or love it.

During the last few weeks Marcus Ramberg was regularly bugging me about
Ruby-on-Rails and how cool their controllers are. (Maypole itself is
currently our only Controller, Struts like)

Now that i had the time, i tried it out and must admit that it's really
a nice design.

But thats not the only thing i'm missing in the current Maypole
implementation, other problmes are that it's much too CDBI/TT2 focused
and doesn't support multiple models/views.

So i began to reimplement Maypole from scratch. (really)

Many concepts are still intact, others were completely removed.
CDBI/TT2 slang for example is gone.

And i also adapted the only feature i liked about Struts, the ability to
separate flow control from the application itself.

But that should be enough for an introduction, now let's go to the
goodies! =)

=== Implementation ===

Here is an example for a new maypole.yaml configuration file:

--- #YAML:1.0
name: Maypole PetStore
root: '/home/sri/PetStore/templates'
base: http://localhost/petstore
models:
  - name: CDBI
    base: CDBI
    dsn: dbi:Pg:dbname=petstore
    user: postgres
    pass: 0
    opts:
      AutoCommit: 1
views:
  - name: TT
    base: TT
controllers:
  - name: Categories
  - name: Cart
  - name: Items
  - name: Products
logic:
  - controller: categories
    action: list
    rules:
      - model: cdbi_category
auth:
  user_class: MyApp::Customer
  user_field: email
  session_class: Apache::Session::Postgres
  session_args:
    DataSource: dbi:Pg:dbname=petstore
    TableName: session
    UserName: postgres
    Password: 0
    Commit: 1

Well, name, root, base and auth are self explaining.

The models, views and controllers sections are there to define the class
layout of our application.

models:
  - name: CDBI
    base: CDBI
    dsn: dbi:Pg:dbname=petstore
    user: postgres
    pass: 0
    opts:
      AutoCommit: 1

Yes, it's an array, and so as much models as you want are supported. ;)

The name will be internally translated to the class "MyApp::Model::CDBI"
and will get "Maypole::Model::CDBI" as it's base class.

The other options will be passed to the setup() method of
"MyApp::Model::CDBI".

Internally we never use class names (we are lazy), so we have aliases.
"CDBI" becomes "cdbi", "MyApp::Model::CDBI::Stuff" becomes "cdbi_stuff".

Maypole::Model::CDBI's setup() automatically creates and loads
subclasses for your tables and registers them with aliases.

Exactly the same thing happens for views and controllers. (Yes, even
setup() gets called for them)

=== Logic ===

The core of all this is logic, it's an intelligent and dynamic internal
mapping between controllers and models.

logic:
  - controller: categories
    action: list
    rules:
      - model: cdbi_category

This small example means that when someone requests
http://localhost/categories/list not only
MyApp::Controller::Categories::list() will be called but also
MyApp::Model::CDBI::Category::list() (and possibly more models and
actions if you define them).

In fact MyApp::Controller::Categories::list() doesn't even have to exist
as method, as soon as its defined in logic it's automatically exported.

The current set of available logic options is not yet finished...so
there is much room for cool features.

logic:
  - controller: categories
    action: list
    rules:
      - model: cdbi_category
        pre:
          - first_post
        post:
          - i_am_late
          - i_am_the_last

Right now i'm thinking about pre and post actions, so the model actions
could be called before and after the controller ones.

Controllers, Models and Views don't communicate directly, they use
$r->objects and $r->trunk to exchange informations.

Views can be dynamically switched by setting
$r->view('some_view_alias').

So it's very very simple to switch between TT2, Mason or a YAML
Serializer. ;)

=== END ===

Now the best thing, this is not pseudo code, i already implemented all
this!
You can grab a (not yet very clean) snapshot at
http://files.oook.de/PetStore.tar.gz

That should be enough to make your heads explode, but there are many
more changes to be exposed! =)

Feedback is very welcome, even when it's "WOW!" or "You Moron!".

sebastian

_______________________________________________
maypole mailing list
maypole at lists.netthink.co.uk
http://lists.netthink.co.uk/listinfo/maypole



This archive was generated by hypermail 2.1.3 : Thu Feb 24 2005 - 22:25:57 GMT