Browse Source

Support "with" in blocktrans tag

Evan Miller 14 years ago
parent
commit
62d4f1d975
3 changed files with 21 additions and 10 deletions
  1. 16 8
      src/erlydtl_compiler.erl
  2. 2 1
      src/erlydtl_parser.yrl
  3. 3 1
      tests/src/erlydtl_unittests.erl

+ 16 - 8
src/erlydtl_compiler.erl

@@ -60,6 +60,7 @@
 -record(ast_info, {
     dependencies = [],
     translatable_strings = [],
+    translatable_blocks= [],
     custom_tags = [],
     var_names = [],
     pre_render_asts = []}).
@@ -482,8 +483,8 @@ body_ast(DjangoParseTree, Context, TreeWalker) ->
                     _ -> Contents
                 end,
                 body_ast(Block, Context, TreeWalkerAcc);
-            ({'blocktrans', {identifier, _, Name}, Contents}, TreeWalkerAcc) ->
-                blocktrans_ast(Name, Contents, Context, TreeWalkerAcc);
+            ({'blocktrans', {identifier, _, Name}, Args, Contents}, TreeWalkerAcc) ->
+                blocktrans_ast(Name, Args, Contents, Context, TreeWalkerAcc);
             ({'call', {'identifier', _, Name}}, TreeWalkerAcc) ->
             	call_ast(Name, TreeWalkerAcc);
             ({'call', {'identifier', _, Name}, With}, TreeWalkerAcc) ->
@@ -653,23 +654,30 @@ with_dependency(FilePath, {{Ast, Info}, TreeWalker}) ->
 empty_ast(TreeWalker) ->
     {{erl_syntax:list([]), #ast_info{}}, TreeWalker}.
 
-blocktrans_ast(Name, Contents, Context, TreeWalker) ->
+blocktrans_ast(Name, ArgList, Contents, Context, TreeWalker) ->
+    {NewScope, {ArgInfo, TreeWalker1}} = lists:mapfoldl(fun
+            ({{identifier, _, LocalVarName}, Value}, {AstInfo1, TreeWalker1}) ->
+                {{Ast, Info}, TreeWalker2} = value_ast(Value, false, Context, TreeWalker1),
+                {{LocalVarName, Ast}, {merge_info(AstInfo1, Info), TreeWalker2}}
+        end, {#ast_info{}, TreeWalker}, ArgList),
+    NewContext = Context#dtl_context{ local_scopes = [NewScope|Context#dtl_context.local_scopes] },
+    {{DefaultAst, AstInfo}, TreeWalker2} = body_ast(Contents, NewContext, TreeWalker1),
+    MergedInfo = merge_info(AstInfo, ArgInfo),
     case Context#dtl_context.blocktrans_fun of
         none ->
-            body_ast(Contents, Context, TreeWalker);
+            {{DefaultAst, MergedInfo}, TreeWalker2};
         BlockTransFun when is_function(BlockTransFun) ->
-            {{DefaultAst, AstInfo}, TreeWalker1} = body_ast(Contents, Context, TreeWalker),
             {FinalAstInfo, FinalTreeWalker, Clauses} = lists:foldr(fun(Locale, {AstInfoAcc, ThisTreeWalker, ClauseAcc}) ->
                         case BlockTransFun(Name, Locale) of
                             default ->
                                 {AstInfoAcc, ThisTreeWalker, ClauseAcc};
                             Body ->
                                 {ok, DjangoParseTree} = parse(Body),
-                                {{ThisAst, ThisAstInfo}, TreeWalker2} = body_ast(DjangoParseTree, Context, ThisTreeWalker),
-                                {merge_info(ThisAstInfo, AstInfoAcc), TreeWalker2, 
+                                {{ThisAst, ThisAstInfo}, TreeWalker3} = body_ast(DjangoParseTree, NewContext, ThisTreeWalker),
+                                {merge_info(ThisAstInfo, AstInfoAcc), TreeWalker3, 
                                     [erl_syntax:clause([erl_syntax:string(Locale)], none, [ThisAst])|ClauseAcc]}
                         end
-                end, {AstInfo, TreeWalker1, []}, Context#dtl_context.blocktrans_locales),
+                end, {MergedInfo, TreeWalker2, []}, Context#dtl_context.blocktrans_locales),
             Ast = erl_syntax:case_expr(erl_syntax:variable("CurrentLocale"),
                 Clauses ++ [erl_syntax:clause([erl_syntax:underscore()], none, [DefaultAst])]),
             {{Ast, FinalAstInfo}, FinalTreeWalker}

+ 2 - 1
src/erlydtl_parser.yrl

@@ -318,7 +318,8 @@ SpacelessBlock -> open_tag spaceless_keyword close_tag Elements open_tag endspac
 SSITag -> open_tag ssi_keyword Value close_tag : {ssi, '$3'}.
 SSITag -> open_tag ssi_keyword string_literal parsed_keyword close_tag : {ssi_parsed, '$3'}.
 
-BlockTransBlock -> open_tag blocktrans_keyword identifier close_tag Elements open_tag endblocktrans_keyword close_tag : {blocktrans, '$3', '$5'}.
+BlockTransBlock -> open_tag blocktrans_keyword identifier close_tag Elements open_tag endblocktrans_keyword close_tag : {blocktrans, '$3', [], '$5'}.
+BlockTransBlock -> open_tag blocktrans_keyword identifier with_keyword Args close_tag Elements open_tag endblocktrans_keyword close_tag : {blocktrans, '$3', '$5', '$7'}.
 
 TemplatetagTag -> open_tag templatetag_keyword Templatetag close_tag : {templatetag, '$3'}.
 

+ 3 - 1
tests/src/erlydtl_unittests.erl

@@ -943,7 +943,9 @@ tests() ->
                 <<"{% blocktrans foo %}Hello{% endblocktrans %}">>, [], <<"Hello">>},
             {"blocktrans choose locale",
                 <<"{% blocktrans hello %}Hello, {{ name }}{% endblocktrans %}">>, [{name, "Mr. President"}], [{locale, "de"}],
-                [{blocktrans_locales, ["de"]}, {blocktrans_fun, fun(hello, "de") -> <<"Guten tag, {{ name }}">> end}], <<"Guten tag, Mr. President">>}
+                [{blocktrans_locales, ["de"]}, {blocktrans_fun, fun(hello, "de") -> <<"Guten tag, {{ name }}">> end}], <<"Guten tag, Mr. President">>},
+            {"blocktrans with args",
+                <<"{% blocktrans foo with var1=foo %}{{ var1 }}{% endblocktrans %}">>, [{foo, "Hello"}], <<"Hello">>}
         ]},
     {"widthratio", [
             {"Literals", <<"{% widthratio 5 10 100 %}">>, [], <<"50">>},