Browse files

Extend the regroup syntax to support nested keys

This commit allows the user to use nested regroup keys. ie.

    {% regroup builds by host.name as hostname_list %}
  • Loading branch information...
1 parent 165b1bf commit e157b4dc695429bc9096e92dd53a2f3868970bf2 @garazdawi garazdawi committed with garazdawi May 18, 2012
Showing with 22 additions and 9 deletions.
  1. +12 −6 src/erlydtl_compiler.erl
  2. +1 −1 src/erlydtl_parser.yrl
  3. +9 −2 src/erlydtl_runtime.erl
View
18 src/erlydtl_compiler.erl
@@ -585,8 +585,8 @@ body_ast(DjangoParseTree, Context, TreeWalker) ->
include_ast(unescape_string_literal(File), Args, Context#dtl_context.local_scopes, Context, TreeWalkerAcc);
({'include_only', {string_literal, _, File}, Args}, TreeWalkerAcc) ->
include_ast(unescape_string_literal(File), Args, [], Context, TreeWalkerAcc);
- ({'regroup', {ListVariable, {identifier, _, Attribute}, {identifier, _, NewVariable}}, Contents}, TreeWalkerAcc) ->
- regroup_ast(ListVariable, Attribute, NewVariable, Contents, Context, TreeWalkerAcc);
+ ({'regroup', {ListVariable, Grouper, {identifier, _, NewVariable}}, Contents}, TreeWalkerAcc) ->
+ regroup_ast(ListVariable, Grouper, NewVariable, Contents, Context, TreeWalkerAcc);
({'spaceless', Contents}, TreeWalkerAcc) ->
spaceless_ast(Contents, Context, TreeWalkerAcc);
({'ssi', Arg}, TreeWalkerAcc) ->
@@ -1038,20 +1038,26 @@ with_ast(ArgList, Contents, Context, TreeWalker) ->
erl_syntax:clause(lists:map(fun({_, Var}) -> Var end, NewScope), none,
[InnerAst])]), ArgAstList), merge_info(ArgInfo, InnerInfo)}, TreeWalker2}.
-regroup_ast(ListVariable, AttributeName, LocalVarName, Contents, Context, TreeWalker) ->
+regroup_ast(ListVariable, GrouperVariable, LocalVarName, Contents, Context, TreeWalker) ->
{{ListAst, ListInfo}, TreeWalker1} = value_ast(ListVariable, false, Context, TreeWalker),
NewScope = [{LocalVarName, erl_syntax:variable(lists:concat(["Var_", LocalVarName]))}],
{{InnerAst, InnerInfo}, TreeWalker2} = body_ast(Contents,
Context#dtl_context{ local_scopes = [NewScope|Context#dtl_context.local_scopes] }, TreeWalker1),
- {{erl_syntax:application(
+ Ast = {erl_syntax:application(
erl_syntax:fun_expr([
erl_syntax:clause([erl_syntax:variable(lists:concat(["Var_", LocalVarName]))], none,
[InnerAst])]),
[erl_syntax:application(erl_syntax:atom(erlydtl_runtime), erl_syntax:atom(regroup),
- [ListAst, erl_syntax:atom(AttributeName)])]), merge_info(ListInfo, InnerInfo)},
- TreeWalker2}.
+ [ListAst, regroup_filter(GrouperVariable,[])])]), merge_info(ListInfo, InnerInfo)},
+ {Ast,TreeWalker2}.
+
+regroup_filter({attribute,{{identifier,_,Ident},Next}},Acc) ->
+ regroup_filter(Next,[erl_syntax:atom(Ident)|Acc]);
+regroup_filter({variable,{identifier,_,Var}},Acc) ->
+ erl_syntax:list([erl_syntax:atom(Var)|Acc]).
+
for_loop_ast(IteratorList, LoopValue, Contents, {EmptyContentsAst, EmptyContentsInfo}, Context, TreeWalker) ->
Vars = lists:map(fun({identifier, _, Iterator}) ->
View
2 src/erlydtl_parser.yrl
@@ -336,7 +336,7 @@ IfNotEqualExpression -> Value : '$1'.
EndIfNotEqualBraced -> open_tag endifnotequal_keyword close_tag.
RegroupBlock -> RegroupBraced Elements EndRegroupBraced : {regroup, '$1', '$2'}.
-RegroupBraced -> open_tag regroup_keyword Value by_keyword identifier as_keyword identifier close_tag : {'$3', '$5', '$7'}.
+RegroupBraced -> open_tag regroup_keyword Value by_keyword Value as_keyword identifier close_tag : {'$3', '$5', '$7'}.
EndRegroupBraced -> open_tag endregroup_keyword close_tag.
SpacelessBlock -> open_tag spaceless_keyword close_tag Elements open_tag endspaceless_keyword close_tag : {spaceless, '$4'}.
View
11 src/erlydtl_runtime.erl
@@ -49,6 +49,13 @@ find_value(Key, Tuple) when is_tuple(Tuple) ->
end
end.
+find_deep_value([Key|Rest],Item) ->
+ case find_value(Key,Item) of
+ undefined -> undefined;
+ NewItem -> find_deep_value(Rest,NewItem)
+ end;
+find_deep_value([],Item) -> Item.
+
fetch_value(Key, Data) ->
case find_value(Key, Data) of
undefined ->
@@ -65,9 +72,9 @@ regroup([], _, []) ->
regroup([], _, [[{grouper, LastGrouper}, {list, LastList}]|Acc]) ->
lists:reverse([[{grouper, LastGrouper}, {list, lists:reverse(LastList)}]|Acc]);
regroup([Item|Rest], Attribute, []) ->
- regroup(Rest, Attribute, [[{grouper, find_value(Attribute, Item)}, {list, [Item]}]]);
+ regroup(Rest, Attribute, [[{grouper, find_deep_value(Attribute, Item)}, {list, [Item]}]]);
regroup([Item|Rest], Attribute, [[{grouper, PrevGrouper}, {list, PrevList}]|Acc]) ->
- case find_value(Attribute, Item) of
+ case find_deep_value(Attribute, Item) of
Value when Value =:= PrevGrouper ->
regroup(Rest, Attribute, [[{grouper, PrevGrouper}, {list, [Item|PrevList]}]|Acc]);
Value ->

0 comments on commit e157b4d

Please sign in to comment.