Swank Wiki
Recently Visited

Swank v0.04.04

Request Handling

A typical CGI setup starts by calling Swank::DefaultApp->new->handler();


Swank::handler first check if it is a raw file extension, such as images and other attachements. Those are served directly.

Next the extension is checked, and defaults to "html". This is the action to call on the page. The requested object is read into the $page global variable, and we essentially just call $page->html (or edit or save, etc).

Actually the top level action is handled slightly differently from other actions. Swank::Security limits what top level actions are allowed. $page->pre_html and $page->post_html are also called before and after the main action, which seemed like a good idea at the time, but it is still looking for a problem to solve.


The main actions are "html" (normal html request), "edit" (shows page in edit mode), "save" (validates and saves changes), and "delete" (deletes the page). There are also actions "attach" (to handle attachments), "submit" (for public forms), "history" (for viewing the page history), and others can be defined.

The "html" action outputs proper html headers and footers, and the page can add to the headers by defining their own "html_head" action or calling $io->html_head directly. In between, it renders the page with a slightly complicated wrapping mechanism. The actual code is:

$self->wrap( next=>$self->{swank_type}, @_ );

"wrap" is another page action, which sets up the other pages which will wrap around this one, and starts the request at the beginning of the wrapping list. (The nowrap parameter can override wrapping behavior.) The next parameter here overrides what the wrapper for this page will call when $self->next is called (given /x/page the default wrapper is /x/site). This means that instead of calling this page, the swank_type for this page is called instead.


$self is the page

$next defaults to "$self->wiki", but here is set to the parent or swank_type, usually /x for /x/page. This causes the wrapping page (/x/site) to call /x instead of /x/page.

$swank_wrap defaults to /x/site for /x/page

and we call "$self->call( "$swank_wrap.wrapper", %args, next=> sub{ $self->call($next,%args) } )" or in other words, $swank_wrap->wrapper(...); , which in turn calls $self->wrap(%args) with $swank_wrap as $self.

So the wrapping list is now: /x/site, /x

This time, $self is /x/site, $next is self.next, and $swank_wrap is /site

So the wrapping list is now /site /x/site /x

/site overrides swank_wrap to be /layout

/layout would wrap from /site again, but that would be a loop, so instead of a doing the loop, it starts the wrapping.

The wrapping list is /layout.wiki, /site.wiki, /x/site.wiki, /x.wiki

For wrapping to work, each of the wrappers much call $self->next where it wants the wrapped page to appear. But /x.wiki does not call self.next. Instead it shows how this page should be laid out and shows the data from $page.