Skip to content
This repository has been archived by the owner on Nov 7, 2018. It is now read-only.

Commit

Permalink
refactoring and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
davebryson committed Feb 14, 2009
1 parent f914ee7 commit 23400f8
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 129 deletions.
91 changes: 39 additions & 52 deletions src/beepbeep.erl
@@ -1,15 +1,37 @@
%% @author Dave Bryson [http://weblog.miceda.org]
%% @copyright Dave Bryson 2008-2009
%%
%% Dispatcher called from the mochiweb server
%% @doc BeepBeep Dispatcher
%%
%% This is called from the MochiWeb server to dispatch
%% requests. Requests are mapped to modules (controllers) and
%% functions (actions) based on path components in the Url. For
%% example, the request:
%%
%% '/feed/show'
%%
%% would get mapped to the module (controller) 'feed' and the function
%% (action) 'show'.
%% By default the root request:
%%
%% '/'
%%
%% is automatically mapped to the module 'home' and the function 'index'
%% Maps Urls to controllers and their views
%%
-module(beepbeep).
-author('Dave Bryson <http://weblog.miceda.org>').

-export([dispatch/1,get_view_file/1]).
-export([dispatch/1,render_template/3]).

%%
%% @doc Dispatches the incoming request to the proper module
%% and function and returns the tuple() from the controller.
%%
%% @spec dispatch(Env::record()) -> tuple()
%%
dispatch(Env) ->
PathComponents = beepbeep_args:path_components(Env),
%% Map the request to our app
{ControllerName,ActionName,Args} = case PathComponents of
[] ->
{"home","index",[]};
Expand All @@ -22,77 +44,42 @@ dispatch(Env) ->
{ok,Controller} ->
process_request(Env,Controller,ActionName,Args);
no_controller ->
%% Try static
%% Try static content using the PATH_INFO
F = beepbeep_args:path(Env),
{static, F}
end.



get_view_file(ViewFile) ->
%%filename:join([get_base_dir()|["views",ViewFile]]),
beepbeep_router:get_view(ViewFile).


%%get_static_path() ->
%% filename:join([get_base_dir()|["www"]]).


%%% Internal below
%%get_base_dir() ->
%% {file, Here} = code:is_loaded(?MODULE),
%% filename:dirname(filename:dirname(Here)).

process_request(Env,ControllerName,ActionName,Args) ->
Env1 = beepbeep_args:set_action(Env,ActionName),
error_logger:info_report(Env1),
Controller = ControllerName:new(Env1),
%%
%% First try the before_filter. If the call returns 'ok', then try the
%% action call. If the action call returns any kind of exit, return
%% {error,no_action}. Otherwise return the response from the Controller
%%
case try_filter(Controller) of
ok ->
case catch(Controller:handle_request(ActionName,Args)) of
{'EXIT',_} ->
{error,no_action};
Response ->
handle_response(Response)
Response -> Response
end;
Any ->
Any
end.

try_filter(ControllerName) ->
case catch(ControllerName:before_filter()) of
{'EXIT', {undef,_}} ->
ok;
Any ->
Any
{'EXIT', {undef,_}} -> ok;
Any -> Any
end.

%% Handle all responses from controller
handle_response({render,View,Data}) ->
{ok,Content} = render_template(View,Data),
{ok,200,"text/html",[],Content};

handle_response({render,View,Data,Options}) ->
{ok,Content} = render_template(View,Data),
{ok,
proplists:get_value(status,Options,200),
proplists:get_value(content_type,Options,"text/html"),
proplists:get_value(headers,Options,[]),
Content};

handle_response({text,Data}) ->
{ok,200,"text/plain",[],Data};

%% This seems stupid...better way??
handle_response({redirect,Url}) ->
{redirect,Url};

handle_response({static,File}) ->
{static,File}.

render_template(ViewFile,Data) ->
FullPathToFile = get_view_file(ViewFile),
error_logger:info_msg("Trying file: ~s~n",[FullPathToFile]),
%%
%% @doc Render the template with the given data.
%% This is called from YOUR_APP_web.erl automatically.
%%
render_template(FullPathToFile,ViewFile,Data) ->
Pieces = string:tokens(ViewFile,"/"),
Name = string:join(Pieces,"_"),
Name1 = filename:basename(Name,".html"),
Expand Down
126 changes: 103 additions & 23 deletions src/beepbeep_args.erl
@@ -1,64 +1,120 @@
%% @author Dave Bryson [http://weblog.miceda.org]
%% @copyright Dave Bryson 2008-2009
%%
%% Main BeepBeep API to use in Controllers
%% @doc Helper functions for accessing request and session information
%% in your controllers.
%%
-module(beepbeep_args).
-compile(export_all).
-export([path/1,
path_components/1,
server_software/1,
server_name/1,
server_protocol/1,
server_port/1,
method/1,
content_type/1,
content_length/1,
remote_addr/1,
get_all_headers/1,
get_param/2,
get_session_id/1,
set_session_id/2,
set_session_data/3,
get_session_data/2,
get_all_session_data/1,
get_action/1,
set_action/2]).
-author('Dave Bryson <http://weblog.miceda.org>').

%% @spec path(Env) -> Path
%% @doc return the path
%%
%% @doc Return the Path
%%
path(Env) ->
proplists:get_value("PATH_INFO",Env).

%% @spec path_components(Env) -> []
%% @doc return the path as an array parsed on the "/"
%%
%% @doc Return the Path as an array parsed on the "/"
%%
path_components(Env) ->
string:tokens(path(Env),"/").

%% @spec server_software(Env) -> ServerSoftware
%% @doc return the name of the server
%%
%% @doc Return the name of the server
%%
server_software(Env) ->
proplists:get_value("SERVER_SOFTWARE", Env).

%% @spec server_name(Env) -> ServerName
%% @doc return the hostname of the server
%%
%% @doc Return the hostname of the server
%%
server_name(Env) ->
proplists:get_value("SERVER_NAME", Env).

%% @spec server_protocol(Env) -> ServerProtocol
%% @doc return the protocol i.e. http
%%
%% @doc Return the protocol
%%
server_protocol(Env) ->
proplists:get_value("SERVER_PROTOCOL", Env).

%%
%% @doc Return the Server port
%%
server_port(Env) ->
proplists:get_value("SERVER_PORT", Env).

%%
%% @doc Return the request method: GET,PUT,POST,DELETE
%%
method(Env) ->
proplists:get_value("REQUEST_METHOD", Env).

%%
%% @doc Return the content-type
%%
content_type(Env) ->
proplists:get_value("CONTENT_TYPE", Env).

%%
%% @doc Return the content_length
%%
content_length(Env) ->
proplists:get_value("CONTENT_LENGTH", Env).

%%
%% @doc Return the Remote address of the client
%%
remote_addr(Env) ->
proplists:get_value("REMOTE_ADDR", Env).

%%
%% @doc Return all Headers
%%
get_all_headers(Env) ->
lists:foldl(fun({"HTTP_" ++ _, _}=Pair, Hdrs) ->
[Pair|Hdrs];
(_, Hdrs) ->
Hdrs
end, [], Env).

%%
%% @doc Return a request Value for a given Key. This contains information
%% from a form POST OR GET query string
%%
get_param(Key,Env) ->
Params = proplists:get_value("beepbeep.data",Env),
proplists:get_value(Key,Params,"?").

%%
%% @doc Get the current session id
%%
get_session_id(Env) ->
proplists:get_value("beepbeep_sid",Env).

%%
%% Sets the session id. This is done internally
%% and should not be used manually
%% @hidden
%%
set_session_id(Value,Env) ->
case lists:keysearch("beepbeep_sid",1,Env) of
{value,_} ->
Expand All @@ -67,18 +123,37 @@ set_session_id(Value,Env) ->
[proplists:property({"beepbeep_sid", Value})|Env]
end.

%% Helpers for accessing Session Data
set_session_data(Env,Key,Value) ->
%%
%% @doc Set a Key,Value in the session
%%
set_session_data(Key,Value,Env) ->
Sid = get_session_id(Env),
beepbeep_session_server:set_session_data(Sid,Key,Value).

get_session_data(Env) ->
%%
%% @doc Return all session data
%%
get_all_session_data(Env) ->
Sid = get_session_id(Env),
beepbeep_session_server:get_session_data(Sid).

%%
%% @doc Get the session data for a given key
%%
get_session_data(Key,Env) ->
proplists:get_value(Key,get_all_session_data(Env)).

%%
%% @doc Return the current requested action
%%
get_action(Env) ->
proplists:get_value("action_name",Env).

%%
%% @doc Warning! Should not be set manually. This is
%% done automatically in the dispather.
%% @hidden
%%
set_action(Env,Value) ->
case lists:keysearch("action_name",1,Env) of
{value,_} ->
Expand All @@ -87,14 +162,19 @@ set_action(Env,Value) ->
[proplists:property({"action_name", Value})|Env]
end.

get_value(Key, Env) ->
proplists:get_value(Key, Env).
%%
%% @doc Set an Key,Value in the environment.
%% Used internally
%% @hidden
set_value(Key, Val, Env) ->
lists:keyreplace(Key, 1, Env, {Key, Val}).

%% get_value(Key, Env) ->
%% proplists:get_value(Key, Env).

get_value(Key, Env, Default) ->
proplists:get_value(Key, Env, Default).
%% get_value(Key, Env, Default) ->
%% proplists:get_value(Key, Env, Default).

get_all_values(Key, Env) ->
proplists:get_all_values(Key, Env).
%% get_all_values(Key, Env) ->
%% proplists:get_all_values(Key, Env).

set_value(Key, Val, Env) ->
lists:keyreplace(Key, 1, Env, {Key, Val}).

0 comments on commit 23400f8

Please sign in to comment.