Changing Mimetypes for Text Responses in BeepBeep
I'm working on a project which I am implementing in BeepBeep. Part of what I am doing is implementing an API where I return results in JSON. This is easy to accomplish if you're rendering a template,
handle_request("index",[]) ->
{render,"home/index.html",[], [{content_type, "application/json"]}.
but there isn't a straightforward way to accomplish it when you just want to return arbitrary binary
or list data instead of rendering a template. It's pretty easy to add the functionality by opening
up your src/PROJECT_web.erl
file and replacing loop/1
with:
loop(Req) ->
%% Setup env...
InitialEnv = mochiweb_env:setup_environment(Req),
Env = setup_session(Req,InitialEnv),
%% Possible return values
%% {render,View,Data}
%% {render,View,Data,Options}
%% {text,Data}
%% {text,Data,Options}
%% {json,Data}
%% {redirect,Url}
%% {static,File}
%% {error,_}
case beepbeep:dispatch(Env) of
{render,View,Data} ->
{ok,Content} = render_template(View,Data,Env),
Req:respond({200,
[{"Content-Type","text/html"}|[get_cookie(Env)]],
Content});
{render,View,Data,Options} ->
{Status,ContentType,Headers} = extract_options(Options, 200, "text/html"),
{ok,Content} = render_template(View,Data,Env),
Req:respond({Status,
[{"Content-Type",ContentType}|[get_cookie(Env)|Headers]],
Content});
{text,Content} ->
Req:respond({200,
[{"Content-Type","text/plain"}|[get_cookie(Env)]],
Content});
{text,Content,Options} ->
{Status,ContentType,Headers} = extract_options(Options, 200, "text/plain"),
Req:respond({Status,
[{"Content-Type",ContentType}|[get_cookie(Env)|Headers]],
Content});
{redirect,Url} ->
Req:respond({302,
[{"Location", Url},
{"Content-Type", "text/html; charset=UTF-8"}],
""});
{static, File} ->
"/" ++ StaticFile = File,
Req:serve_file(StaticFile,skel_deps:local_path(["www"]));
{error,_} ->
Req:respond({500,[],"Server Error"})
end.
And replace get_options/1
with:
extract_options(Options, DefaultStatus, DefaultMimetype) ->
{proplists:get_value(status,Options,DefaultStatus),
proplists:get_value(content_type,Options,DefaultMimetype),
proplists:get_value(headers,Options,[])}.
Then you can return arbitrary data with arbitrary mimetypes.
handle_request("index",[]) ->
Json = mochijson:encode({struct, [{a, "b"}, {b, "c"}]}),
{text, Json, [{content_type, "application/json"]}.
You can patch your projects, or grab my patched version of BeepBeep, although hopefully we'll be able to upstream this patch without much trouble.