Hi Kevin,
I was just looking into this tonight as well. I've attached what I'm
working with so far.
On Jan 2, 6:47 pm, "Kevin A. Smith" <[EMAIL PROTECTED]> wrote:
> * yaws_args/yaws_headers - This looks pretty straightforward. We'd
> just need to replace yaws api calls with the corresponding ewgi calls.
> ewgi appears to be missing cookie support in ewgi_api but I think I
> could add that. Does this sound about right?
instead of yaws_arg going everywhere, I created a erlyweb_arg which
should be used throughout erlyweb and has an interface for both ewgi
and yaws.
> * erlyweb:out/1 -- I'm hung up on this one and looking for some ideas.
> Yaws calls this function directly for each request. Does ewgi have
> something we could shim in here in its place? I'm thinking of some
> sort of appmod that proxies yaws calls into Erlyweb.
I took this out of the erlyweb module and put it in
erlyweb_interface_yaws. the entry point into request parsing for
erlyweb is now erlyweb:handle_request/3. I started an
erlyweb_interface_ewgi which will (eventually) convert erlyweb's
response into something that ewgi can handle ( strip out all the ehtml
and header-specific stuff ).
a lot more needs to be done, just want to put it out there for review.
-Adam
Index: erlyweb_forms.erl
===================================================================
--- erlyweb_forms.erl (revision 228)
+++ erlyweb_forms.erl (working copy)
@@ -35,7 +35,7 @@
%% @spec to_recs(A::arg() | [{ParamName::string(),
ParamVal::term()}],
%% [{Prefix::string(), Model::atom()}]) -> [Record::tuple()]
to_recs(A, ModelDescs) when is_tuple(A), element(1, A) == arg ->
- to_recs(yaws_api:parse_post(A), ModelDescs);
+ to_recs(erlyweb_arg:parse_post(A), ModelDescs);
to_recs(Params, ModelDescs) ->
Models =
[{Prefix, Model, Model:new()} || {Prefix, Model} <- ModelDescs],
@@ -95,7 +95,7 @@
%% Fun::function()) -> {Values::[term()], Errors::[term()]} |
%% exit({missing_param, Field})
validate(A, Fields, Fun) when is_tuple(A), element(1, A) == arg ->
- validate(yaws_api:parse_post(A), Fields, Fun);
+ validate(erlyweb_arg:parse_post(A), Fields, Fun);
validate(Params, Fields, Fun) ->
lists:foldr(
fun(Field, Acc) ->
@@ -115,7 +115,7 @@
%% Fun::function()) -> {Vals, Errs} | exit({missing_params,
[string()]}) |
%% exit({unexpected_params, proplist()}) | exit({unexpected_param,
string()})
validate1(A, Fields, Fun) when is_tuple(A), element(1, A) == arg ->
- validate1(yaws_api:parse_post(A), Fields, Fun);
+ validate1(erlyweb_arg:parse_post(A), Fields, Fun);
validate1(Params, Fields, Fun) ->
validate1_1(Params, Fields, Fun, {[], []}).
Index: erlyweb_arg.erl
===================================================================
--- erlyweb_arg.erl (revision 0)
+++ erlyweb_arg.erl (revision 0)
@@ -0,0 +1,38 @@
+-module(erlyweb_arg).
+-export([create/2]).
+-export([opaque/1,appmoddata/1,server_path/1,method/1,parse_post/1]).
+-export([props/1,prop_insert/2,prop_find/2]).
+-export([app_data/1,app_data/2,app_controller/1,app_controller/2]).
+
+create(Mod,Arg) ->
+ {Mod,Arg,[]}.
+appmoddata({Mod,Arg,_}) ->
+ Mod:appmoddata(Arg).
+server_path({Mod,Arg,_}) ->
+ Mod:server_path(Arg).
+method({Mod,Arg,_}) ->
+ Mod:method(Arg).
+parse_post({Mod,Arg,_}) ->
+ Mod:parse_post(Arg).
+
+props({_,_,O}) ->
+ O.
+prop_insert({Mod,Arg,O},{Key,Val}) ->
+ O2 = case proplists:is_defined(Key,O) of
+ true -> proplists:delete(Key,O);
+ _ -> O
+ end,
+ {Mod,Arg,[{Key,Val}|O2]}.
+prop_find({_,_,O},Key) ->
+ proplists:lookup(Key,O).
+
+app_data(Arg) ->
+ prop_find(Arg,app_data_module).
+app_data(Arg,AppData) ->
+ prop_insert(Arg,{app_data_module,AppData}).
+
+app_controller(Arg) ->
+ prop_find(Arg,app_controller_module).
+app_controller(Arg,AppData) ->
+ prop_insert(Arg,{app_controller_module,AppData}).
+
Index: erlyweb_interface_ewgi.erl
===================================================================
--- erlyweb_interface_ewgi.erl (revision 0)
+++ erlyweb_interface_ewgi.erl (revision 0)
@@ -0,0 +1,12 @@
+-module(erlyweb_interface_ewgi).
+
+handle_req(Env,StartResp) ->
+ Arg = erlyweb_arg_ewgi:create(Env),
+ { Arg2 , AppController , AppData } =
erlyweb:prepare_request(Arg),
+ Resp = erlyweb:handle_request(Arg2,AppController,AppData),
+ handle_response(Env,StartResp,Resp).
+
+% filter out all the ehtml/yaws return stuff (ewgi-ify the response).
+handle_response(Env,StartResp,Resp) ->
+ todo.
+
Index: erlyweb_arg_yaws.erl
===================================================================
--- erlyweb_arg_yaws.erl (revision 0)
+++ erlyweb_arg_yaws.erl (revision 0)
@@ -0,0 +1,15 @@
+-module(erlyweb_arg_yaws).
+-export([create/1]).
+-export([appmoddata/1,server_path/1,method/1,parse_post/1]).
+
+create(A) ->
+ erlyweb_arg:create(?MODULE,A).
+appmoddata(A) ->
+ yaws_arg:appmoddata(A).
+server_path(A) ->
+ yaws_arg:server_path(A).
+method(A) ->
+ yaws_arg:method(A).
+parse_post(A) ->
+ yaws_api:parse_post(A).
+
Index: erlyweb_util.erl
===================================================================
--- erlyweb_util.erl (revision 228)
+++ erlyweb_util.erl (working copy)
@@ -11,8 +11,7 @@
-module(erlyweb_util).
-author("Yariv Sadan ([EMAIL PROTECTED], http://yarivsblog.com").
-export([log/5, create_app/2, create_component/3,
- get_url_prefix/1,
- get_cookie/2, indexify/2]).
+ get_url_prefix/1, indexify/2]).
-define(Debug(Msg, Params), log(?MODULE, ?LINE, debug, Msg, Params)).
-define(Info(Msg, Params), log(?MODULE, ?LINE, info, Msg, Params)).
@@ -234,17 +233,8 @@
lists:dropwhile(
fun($?) -> true;
(_) -> false
- end, yaws_arg:appmoddata(A)).
+ end, erlyweb_arg:appmoddata(A)).
-
-%% @doc Get the cookie's value from the arg.
-%% @equiv yaws_api:find_cookie_val(Name, yaws_headers:cookie(A))
-%%
-%% @spec get_cookie(Name::string(), A::arg()) -> string()
-get_cookie(Name, A) ->
- yaws_api:find_cookie_val(
- Name, yaws_headers:cookie(A)).
-
%% @doc Translate requests such as '/foo/bar' to '/foo/index/bar' for
the given
%% list of components. This function is useful for rewriting the Arg
in the
%% app controller prior to handling incoming requests.
@@ -254,14 +244,14 @@
%%
%% @spec indexify(A::arg(), ComponentNames::[string()]) -> arg()
indexify(A, ComponentNames) ->
- Appmod = yaws_arg:appmoddata(A),
- Sp = yaws_arg:server_path(A),
+ Appmod = erlyweb_arg:appmoddata(A),
+ Sp = erlyweb_arg:server_path(A),
Appmod1 = indexify1(Appmod, ComponentNames),
- A1 = yaws_arg:appmoddata(A, Appmod1),
+ A1 = erlyweb_arg:appmoddata(A, Appmod1),
{SpRoot, _} = lists:split(length(Sp) - length(Appmod), Sp),
- yaws_arg:server_path(A1, SpRoot ++ Appmod1).
+ erlyweb_arg:server_path(A1, SpRoot ++ Appmod1).
indexify1(S1, []) -> S1;
Index: erlyweb.erl
===================================================================
--- erlyweb.erl (revision 228)
+++ erlyweb.erl (working copy)
@@ -145,52 +145,6 @@
compile(AppDir, Options) ->
erlyweb_compile:compile(AppDir, Options).
-
-%% @doc This is the out/1 function that Yaws calls when passing
-%% HTTP requests to the ErlyWeb appmod.
-%%
-%% @spec out(A::yaws_arg()) -> ret_val()
-out(A) ->
- AppName = get_app_name(A),
- AppData = erlyweb_compile:get_app_data_module(AppName),
- AppController =
- case catch AppData:get_controller() of
- {'EXIT', {undef, _}} ->
- exit({no_application_data,
- "Did you forget to call erlyweb:compile(AppDir) "
- "or add the app's previously compiled .beam "
- "files to the Erlang code path?"});
- Other1 ->
- Other1
- end,
- case AppData:auto_compile() of
- false -> ok;
- {true, Options} ->
- auto_compile(A, AppData, Options)
- end,
-
- out(yaws_arg:add_to_opaque(
- A, {app_data_module, AppData}), AppController).
-
-%% @doc This function is useful for embedding the result of a
'phased'
-%% ErlyWeb rendering in an ErlyWeb component from the same
application,
-%% but using a different app controller.
-%%
-%% This function was originally designed to simplify Facebook app
development
-%% with ErlyWeb using Erlang2Facebook
-%% (http://code.google.com/p/erlang2facebook).
-%% In erlang2facebook, the fb_canvas component intercepts requests
-%% from Facebook and authenticates them. After authentication, it may
be
-%% useful to start a new ErlyWeb "flow" using an alternative app
controller
-%% and display the result in of this flow the output of fb_canvas.
-%%
-%% @spec out(A::arg(), AppController::atom()) -> term()
-out(A, AppController) ->
- AppData = proplists:get_value(app_data_module,
yaws_arg:opaque(A)),
- handle_request(A,
- AppController, AppController:hook(A),
- AppData).
-
%% checks that at least 3 seconds have passed since the last
compilation
%% and that the request doesn't match the optional
auto_compile_exclude
%% value.
@@ -204,7 +158,7 @@
case lists:keysearch(auto_compile_exclude, 1,
Options) of
{value, {_, Val}} ->
- case string:str(yaws_arg:appmoddata(A),
+ case string:str(erlyweb_arg:appmoddata(A),
Val) of
1 -> ok;
_ -> auto_compile1(AppData, Options)
@@ -222,6 +176,33 @@
Err -> exit(Err)
end.
+prepare_request(A) ->
+ AppName = get_app_name(Arg),
+ AppData = erlyweb_compile:get_app_data_module(AppName),
+ AppController =
+ case catch AppData:get_controller() of
+ {'EXIT', {undef, _}} ->
+ exit({no_application_data,
+ "Did you forget to call erlyweb:compile(AppDir) "
+ "or add the app's previously compiled .beam "
+ "files to the Erlang code path?"});
+ Other1 ->
+ Other1
+ end,
+ case AppData:auto_compile() of
+ false -> ok;
+ {true, Options} ->
+ auto_compile(A, AppData, Options)
+ end,
+ A2 = erlyweb_arg:app_data(A,AppData),
+ A3 = erlyweb_arg:app_controller(A,AppController),
+ { A3 , AppController , AppData }.
+
+handle_request(A,AppController,AppData) ->
+ handle_request(A,
+ AppController, AppController:hook(A),
+ AppData).
+
handle_request(A,
AppController,
{phased, Ewc, Func}, AppData) ->
@@ -317,7 +298,7 @@
element(1, get_initial_ewc1(Ewc)).
get_initial_ewc1({ewc, A} = Ewc) ->
- AppData = lookup_app_data_module(A),
+ AppData = erlyweb_arg:app_data(A),
get_initial_ewc1(Ewc, AppData).
get_initial_ewc1({ewc, A}, AppData) ->
case get_ewc(A, AppData) of
@@ -472,7 +453,7 @@
end.
get_ewc(A) ->
- get_ewc(A, lookup_app_data_module(A)).
+ get_ewc(A, erlyweb_arg:app_data(A)).
get_ewc(A, AppData) ->
Prefix = erlyweb_util:get_url_prefix(A),
@@ -492,7 +473,7 @@
{error, no_such_component} ->
%% if the request doesn't match a controller's name,
%% redirect it to /path
- Path = case yaws_arg:appmoddata(A) of
+ Path = case erlyweb_arg:appmoddata(A) of
[$/ | _ ] = P -> P;
Other -> [$/ | Other]
end,
@@ -508,7 +489,7 @@
%%
%% @spec get_app_name(A::arg()) -> AppName::string() | exit(Err)
get_app_name(A) ->
- case proplists:get_value("appname", yaws_arg:opaque(A)) of
+ case proplists:get_value("appname", erlyweb_arg:opaque(A)) of
undefined ->
exit({missing_appname,
"Did you forget to add the 'appname = [name]' "
@@ -523,14 +504,11 @@
%%
%% @spec get_app_root(A::arg()) -> string()
get_app_root(A) ->
- ServerPath = yaws_arg:server_path(A),
+ ServerPath = erlyweb_arg:server_path(A),
{First, _Rest} =
lists:split(
length(ServerPath) -
- length(yaws_arg:appmoddata(A)),
+ length(erlyweb_arg:appmoddata(A)),
ServerPath),
First.
-lookup_app_data_module(A) ->
- proplists:get_value(app_data_module, yaws_arg:opaque(A)).
-
Index: erlyweb_interface_yaws.erl
===================================================================
--- erlyweb_interface_yaws.erl (revision 0)
+++ erlyweb_interface_yaws.erl (revision 0)
@@ -0,0 +1,8 @@
+-module(erlyweb_interface_yaws).
+-export([out/1]).
+
+out(A) ->
+ Arg = erlyweb_arg:create(erlyweb_arg_yaws,A),
+ { Arg2 , AppController , AppData } =
erlyweb:prepare_request(Arg),
+ erlyweb:handle_request(Arg2,AppController,AppData).
+
Index: erlyweb_arg_ewgi.erl
===================================================================
--- erlyweb_arg_ewgi.erl (revision 0)
+++ erlyweb_arg_ewgi.erl (revision 0)
@@ -0,0 +1,12 @@
+-module(erlyweb_arg_ewgi).
+
+create(Env) ->
+ erlyweb_arg:create(?MODULE,Env).
+appmoddata(Env) ->
+ todo.
+server_path(Env) ->
+ todo.
+method(A) ->
+ todo.
+parse_post(A) ->
+ todo.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"erlyweb" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to [EMAIL PROTECTED]
For more options, visit this group at
http://groups.google.com/group/erlyweb?hl=en
-~----------~----~----~----~------~----~------~--~---