Updated July 20 2007: new params.erl which uses dict to store params and converts to proper type(integer/float/string)
It's time to migrate our project from Rails to Erlyweb (It cost me one month to write an Erlang IDE before this happens :-)). I'll blog some tips of the procedure, focus on the differences between Rails and erlyweb.
page = params.fetch(:p, 1).to_i size = params.fetch(:s, @@RECORDS_PER_PAGE).to_iErlyweb:
-module(mymodel_controller).. -define(RECORDS_PER_PAGE, 9). list(A) -> P = params:from_yaws_arg(A) Page = params:get("p", P, 1), %% return integer Size = params:get("s", P, ?RECORDS_PER_PAGE), ....
You can also
Id = params:get("id", P, integer) %% return integer() Id = params:get("id", P) %% return string() %% Or, pass a fun to return the converted result Id = params:get("id", P, fun string:to_integer/1)To get the above code working, I wrote a params.erl and placed under folder: apps\myapp\lib.
-module(params). -export([ from_yaws_arg/1, from_list/1, get_page_opts/1, get_page_extras/1, get/2, get/3, get/4, convert/2, put/3, join/1 ]). %% @doc Convert yaws Arg#arg.querydata into a {key,value} stored in a dynamic hash. from_yaws_arg(Arg) -> Params = yaws_api:parse_query(Arg), dict:from_list(Params). from_list(PropsList) -> dict:from_list(PropsList). get_page_opts(Dict) -> [{page, get("p", Dict, 1)}, {page_size, get("s", Dict, ?DEFAULT_PAGESIZE)}]. get_page_extras(Dict) -> Page = get("p", Dict, 1), Size = get("s", Dict, ?DEFAULT_PAGESIZE), Offset = (Page - 1) * Size, [{limit, Offset, Size}]. get(Key, Dict) -> get(Key, Dict, undefined). %% @spec get(Key::term(), Arg:yawsArg(), Default::term() -> string() get(Key, Dict, Fun) when is_function(Fun) -> case get(Key, Dict, undefined) of undefined -> undefined; Value -> Fun(Value) end; get(Key, Dict, Type) when is_atom(Type) andalso Type /= undefined -> get(Key, Dict, undefined, Type); get(Key, Dict, Default) -> case dict:find(Key, Dict) of {ok, Value} when is_list(Default) -> convert(Value, string); {ok, Value} when is_integer(Default) -> convert(Value, integer); {ok, Value} when is_float(Default) -> convert(Value, float); {ok, Value} -> Value; error -> Default end. get(Key, Dict, Default, Type) -> Value = get(Key, Dict, Default), convert(Value, Type). convert(Value, _Type) when Value == undefined -> undefined; convert(Value, Type) -> try case Type of integer when is_list(Value) -> list_to_integer(Value); integer when is_integer(Value) -> Value; integer when is_float(Value) -> erlang:round(Value); float when is_list(Value) -> list_to_float(Value); float when is_integer(Value) -> Value * 1.0; float when is_float(Value) -> Value; string when is_list(Value) -> Value; string when is_integer(Value) -> integer_to_list(Value); string when is_float(Value) -> float_to_list(Value); number when is_list(Value) andalso Value /= "" andalso Value /= "NaN" -> case string:chr(Value, $.) > 0 of true -> list_to_float(Value); false -> list_to_integer(Value) end; number when is_integer(Value) -> Value; number when is_float(Value) -> Value end catch error:_ -> undefined end. put(Key, Value, Dict) -> dict:store(Key, Value, Dict). join(Params) -> ParamPairedStrs = dict:fold( fun (Key, Value, Acc) -> [Key ++ "=" ++ yaws_api:url_encode(Value)|Acc] end, [], Params), %% Join params string with "&": ["a=a1", "b=b1"] => "a=a1&b=b1" join("&", ParamPairedStrs). %% @spec join(string(), list(string())) -> string() join(String, List) -> join(String, List, []). join(_String, [], Joined) -> Joined; join(String, [H|[]], Joined) -> join(String, [], Joined ++ H); join(String, [H|T], Joined) -> join(String, T, Joined ++ H ++ String).