Skip to content

Instantly share code, notes, and snippets.

@ArthurClemens
Last active August 29, 2015 13:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ArthurClemens/8875446 to your computer and use it in GitHub Desktop.
Save ArthurClemens/8875446 to your computer and use it in GitHub Desktop.
%% @doc
%% Filter module for Zotonic
%% 'foldl' filter, applies foldl to a list
%%
%% Usage:
%% {{ [1,2,3]|foldl:["*", 1] }}
%% {{ [1,2,3]|foldl:["+", 0] }}
%% {{ ["a", "b", "c"]|foldl:["++", ""] }}
%%
%% Pass an attribute to fetch for each item:
%% {{ user.o.shopping_basket|make_list|foldl:["price", "+", 0] }}
%% @end
-module(filter_foldl).
-export([
foldl/3
]).
foldl(Items, Args, Context) ->
case Args of
[Op, Acc] -> foldl_list(Items, [Op, Acc], Context);
[Attr, Op, Acc] -> foldl_list_attr(Items, [Attr, Op, Acc], Context)
end.
foldl_list(Items, [Op, Acc], _Context) ->
lists:foldl(fun(Item, Acc1) ->
parse(Acc1, Op, Item)
end, Acc, Items).
foldl_list_attr(Items, [Attr, Op, Acc], Context) ->
lists:foldl(fun(Item, Acc1) ->
Prop = m_rsc:p(Item, Attr, Context),
parse(Acc1, Op, Prop)
end, Acc, Items).
parse(Val1, Op, Val2) ->
Val1Str = z_convert:to_list(Val1),
Val2Str = z_convert:to_list(Val2),
Expr = case Op of
"++" -> escape_string(Val1Str) ++ " " ++ Op ++ " " ++ escape_string(Val2Str);
_ -> Val1Str ++ " " ++ Op ++ " " ++ Val2Str
end,
{ok, Tokens, _} = erl_scan:string(Expr ++ "."),
{ok, Abstract} = erl_parse:parse_exprs(Tokens),
Bindings = erl_eval:new_bindings(),
{value, Value, _} = erl_eval:exprs(Abstract, Bindings),
Value.
escape_string(V) -> "\"" ++ V ++ "\"".
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment