Rails Idioms + Django Templates + Erlang Power = Chicago BOSS

The Chicago Boss API is mostly stable, but still might change before 1.0.

Jump to:   Return values   SimpleBridge request object

Chicago Boss associates each URL with a function of a controller. The URL /foo/bar will call the function foo_controller:bar. Each controller module should go into your project's Web/ directory and the file name should end with "_controller.erl". Helper functions should go in modules that end in "_lib.erl". Controllers should take one parameter, the SimpleBridge request object. Declare it like:

-module(my_controller, [Req]).

Each exported controller function takes two or three arguments:

  • First argument: the HTTP request method as an atom, e.g. 'GET' or 'POST'
  • Second argument: the list of slash-separated tokens after the action name in the URL.
  • Third argument (optional): the result of a function named '_auth' in the controller

Example function clauses:

% GET /blog/view
view('GET', []) ->
    ...
% GET /blog/view/1234
view('GET', [Id]) ->
    ...
% GET /blog/view/tag/funny
view('GET', ["tag", Tag]) ->
    ...
% GET /blog/view/tag/funny/author/saint-paul
view('GET', ["tag", Tag, "author", AuthorName]) ->
    ...
% GET /blog/view/2009/08
view('GET', [Year, Month]) ->
    ...

If an action takes three arguments, then the function '_auth'/1 in your controller will be passed the action name as an atom and should return one of:

{ok, ExtraInfo}

ExtraInfo will be passed as the third argument to the action.

{redirect, Location::string()}

Do not execute the action. Instead, perform a 302 redirect to Location.

Probably most common _auth looks like:

'_auth'(_) ->
    my_user_lib:require_login(Req).

Which might return a tuple of user credential or else redirect to a login page. This way, if you want to require a login to a set of actions, just give those actions a User argument, and the actions will be login protected and have access to the User variable.



Whether or not it takes a third argument, a controller action should return with one of the following:

ok

The template will be rendered without any variables.

{ok, Variables::proplist()}

Variables will be passed into the associated Django template.

{ok, Variables::proplist(), Headers::proplist()}

Variables will be passed into the associated Django template, and Headers are HTTP headers you want to set (e.g., Content-Type).

{redirect, Location::string()}

Perform a 302 HTTP redirect to Location.

{redirect, Location::string(), Headers::proplist()}

Perform a 302 HTTP redirect to Location and set additional HTTP Headers.

{action_other, OtherLocation}

OtherLocation = {Controller::atom(), Action::atom()}

Execute the specified controller action, but without performing an HTTP redirect.

{render_other, OtherLocation}

OtherLocation = {Controller::atom(), Action::atom()}

Render the view from OtherLocation, but don't actually execute the associated controller action.

{render_other, OtherLocation, Variables}

OtherLocation = {Controller::atom(), Action::atom()}

Render the view from OtherLocation using Variables, but don't actually execute the associated controller action.

{output, Output::iolist()}

Skip views altogether and return Output to the client.

{output, Output::iolist(), Headers::proplist()}

Skip views altogether and return Output to the client while setting additional HTTP Headers.



Controller functions are passed a SimpleBridge request object (slightly modified for Boss's purposes). Useful functions in the request object include:

request_method() -> atom()

Get the request method, e.g. GET, POST, etc.

query_param( Key::string() ) -> string() | undefined

Get the value of a given query string parameter (e.g. "?id=1234")

post_param( Key::string() ) -> string() | undefined

Get the value of a given POST parameter

header( Key::string() ) -> string() | undefined

Get the value of a given HTTP request header

cookie( Key::string() ) -> string() | undefined

Get the value of a given cookie.