Browse Source

add language tag (#212).

Andreas Stenius 9 years ago
parent
commit
11f4bf03e2

+ 11 - 7
src/erlydtl_beam_compiler.erl

@@ -225,7 +225,7 @@ compile_to_binary(DjangoParseTree, CheckSum, Context) ->
 compile_forms(Forms, Context) ->
 compile_forms(Forms, Context) ->
     maybe_debug_template(Forms, Context),
     maybe_debug_template(Forms, Context),
     Options = Context#dtl_context.compiler_options,
     Options = Context#dtl_context.compiler_options,
-    case compile:forms(Forms, Options) of
+    case compile:forms(Forms, [nowarn_shadow_vars|Options]) of
         Compiled when element(1, Compiled) =:= ok ->
         Compiled when element(1, Compiled) =:= ok ->
             [ok, Module, Bin|Info] = tuple_to_list(Compiled),
             [ok, Module, Bin|Info] = tuple_to_list(Compiled),
             lists:foldl(
             lists:foldl(
@@ -589,9 +589,10 @@ body_ast([{'extends', {string_literal, _Pos, String}} | ThisParseTree], #treewal
     end;
     end;
 
 
 body_ast(DjangoParseTree, TreeWalker) ->
 body_ast(DjangoParseTree, TreeWalker) ->
-    body_ast(DjangoParseTree, empty_scope(), TreeWalker).
+    ScopeFun = fun ([ScopeVars|ScopeBody]) -> [?Q("(fun() -> _@ScopeVars, [_@ScopeBody] end)()")] end,
+    body_ast(DjangoParseTree, empty_scope(), ScopeFun, TreeWalker).
 
 
-body_ast(DjangoParseTree, BodyScope, TreeWalker) ->
+body_ast(DjangoParseTree, BodyScope, ScopeFun, TreeWalker) ->
     {ScopeId, TreeWalkerScope} = begin_scope(BodyScope, TreeWalker),
     {ScopeId, TreeWalkerScope} = begin_scope(BodyScope, TreeWalker),
     BodyFun =
     BodyFun =
         fun ({'autoescape', {identifier, _, OnOrOff}, Contents}, TW) ->
         fun ({'autoescape', {identifier, _, OnOrOff}, Contents}, TW) ->
@@ -606,7 +607,7 @@ body_ast(DjangoParseTree, BodyScope, TreeWalker) ->
                                   BlockScope = create_scope(
                                   BlockScope = create_scope(
                                                  [{block, ?Q("fun (super) -> _@SuperAst; (_) -> [] end"), safe}],
                                                  [{block, ?Q("fun (super) -> _@SuperAst; (_) -> [] end"), safe}],
                                                  ChildPos, ChildFile, AccTW),
                                                  ChildPos, ChildFile, AccTW),
-                                  {{BlockAst, BlockInfo}, BlockTW} = body_ast(ChildBlock, BlockScope, AccTW),
+                                  {{BlockAst, BlockInfo}, BlockTW} = body_ast(ChildBlock, BlockScope, ScopeFun, AccTW),
                                   {{BlockAst, merge_info(SuperInfo, BlockInfo)}, BlockTW}
                                   {{BlockAst, merge_info(SuperInfo, BlockInfo)}, BlockTW}
                           end,
                           end,
                           ContentsAst, ChildBlocks);
                           ContentsAst, ChildBlocks);
@@ -724,6 +725,11 @@ body_ast(DjangoParseTree, BodyScope, TreeWalker) ->
                 extension_ast(Tag, TW);
                 extension_ast(Tag, TW);
             ({'extends', _}, TW) ->
             ({'extends', _}, TW) ->
                 empty_ast(?ERR(unexpected_extends_tag, TW));
                 empty_ast(?ERR(unexpected_extends_tag, TW));
+            ({'language', Locale, Contents}, TW) ->
+                {{LocaleAst, LocaleInfo}, LocaleTW} = value_ast(Locale, true, false, TW),
+                LanguageScopeFun = fun ([ScopeVars|ScopeBody]) -> [?Q("(fun(_CurrentLocale) -> _@ScopeVars, [_@ScopeBody] end)(_@LocaleAst)")] end,
+                {{BodyAst, BodyInfo}, BodyTW} = body_ast(Contents, {[], [?Q("")]}, LanguageScopeFun, LocaleTW),
+                {{BodyAst, merge_info(BodyInfo, LocaleInfo)}, BodyTW};
             (ValueToken, TW) ->
             (ValueToken, TW) ->
                 format(value_ast(ValueToken, true, true, TW))
                 format(value_ast(ValueToken, true, true, TW))
         end,
         end,
@@ -736,9 +742,7 @@ body_ast(DjangoParseTree, BodyScope, TreeWalker) ->
                   {Ast, merge_info(Info, InfoAcc)}
                   {Ast, merge_info(Info, InfoAcc)}
           end, #ast_info{}, AstInfoList),
           end, #ast_info{}, AstInfoList),
 
 
-    {Ast, TreeWalker2} = end_scope(
-                           fun ([ScopeVars|ScopeBody]) -> [?Q("(fun() -> _@ScopeVars, [_@ScopeBody] end)()")] end,
-                           ScopeId, AstList, TreeWalker1),
+    {Ast, TreeWalker2} = end_scope(ScopeFun, ScopeId, AstList, TreeWalker1),
     {{erl_syntax:list(Ast), Info}, TreeWalker2}.
     {{erl_syntax:list(Ast), Info}, TreeWalker2}.
 
 
 
 

+ 11 - 0
src/erlydtl_parser.yrl

@@ -66,6 +66,10 @@ Nonterminals
     IncludeTag
     IncludeTag
     NowTag
     NowTag
 
 
+    LanguageBlock
+    LanguageBraced
+    EndLanguageBraced
+
     FirstofTag
     FirstofTag
 
 
     FilterBlock
     FilterBlock
@@ -171,6 +175,7 @@ Terminals
     endifchanged_keyword
     endifchanged_keyword
     endifequal_keyword
     endifequal_keyword
     endifnotequal_keyword
     endifnotequal_keyword
+    endlanguage_keyword
     endregroup_keyword
     endregroup_keyword
     endspaceless_keyword
     endspaceless_keyword
     endwith_keyword
     endwith_keyword
@@ -186,6 +191,7 @@ Terminals
     ifnotequal_keyword
     ifnotequal_keyword
     in_keyword
     in_keyword
     include_keyword
     include_keyword
+    language_keyword
     load_keyword
     load_keyword
     noop_keyword
     noop_keyword
     not_keyword
     not_keyword
@@ -252,6 +258,7 @@ Elements -> Elements IfEqualBlock : '$1' ++ ['$2'].
 Elements -> Elements IfNotEqualBlock : '$1' ++ ['$2'].
 Elements -> Elements IfNotEqualBlock : '$1' ++ ['$2'].
 Elements -> Elements IfChangedBlock : '$1' ++ ['$2'].
 Elements -> Elements IfChangedBlock : '$1' ++ ['$2'].
 Elements -> Elements IncludeTag : '$1' ++ ['$2'].
 Elements -> Elements IncludeTag : '$1' ++ ['$2'].
+Elements -> Elements LanguageBlock : '$1' ++ ['$2'].
 Elements -> Elements LoadTag : '$1' ++ ['$2'].
 Elements -> Elements LoadTag : '$1' ++ ['$2'].
 Elements -> Elements NowTag : '$1' ++ ['$2'].
 Elements -> Elements NowTag : '$1' ++ ['$2'].
 Elements -> Elements RegroupTag : '$1' ++ ['$2'].
 Elements -> Elements RegroupTag : '$1' ++ ['$2'].
@@ -294,6 +301,10 @@ BlockBlock -> BlockBraced Elements EndBlockBraced : {block, '$1', '$2'}.
 BlockBraced -> open_tag block_keyword identifier close_tag : '$3'.
 BlockBraced -> open_tag block_keyword identifier close_tag : '$3'.
 EndBlockBraced -> open_tag endblock_keyword close_tag.
 EndBlockBraced -> open_tag endblock_keyword close_tag.
 
 
+LanguageBlock -> LanguageBraced Elements EndLanguageBraced : {language, '$1', '$2'}.
+LanguageBraced -> open_tag language_keyword Value close_tag : '$3'.
+EndLanguageBraced -> open_tag endlanguage_keyword close_tag.
+
 ExtendsTag -> open_tag extends_keyword string_literal close_tag : {extends, '$3'}.
 ExtendsTag -> open_tag extends_keyword string_literal close_tag : {extends, '$3'}.
 
 
 IncludeTag -> open_tag include_keyword string_literal close_tag : {include, '$3', []}.
 IncludeTag -> open_tag include_keyword string_literal close_tag : {include, '$3', []}.

+ 3 - 1
src/erlydtl_scanner.erl

@@ -36,7 +36,7 @@
 %%%-------------------------------------------------------------------
 %%%-------------------------------------------------------------------
 -module(erlydtl_scanner).
 -module(erlydtl_scanner).
 
 
-%% This file was generated 2014-12-16 18:46:16 UTC by slex 0.2.1-2-g7814678.
+%% This file was generated 2015-10-16 21:31:55 UTC by slex 0.2.1-2-g7814678.
 %% http://github.com/erlydtl/slex
 %% http://github.com/erlydtl/slex
 -slex_source(["src/erlydtl_scanner.slex"]).
 -slex_source(["src/erlydtl_scanner.slex"]).
 
 
@@ -106,6 +106,8 @@ is_keyword(open, "autoescape") -> true;
 is_keyword(open, "endautoescape") -> true;
 is_keyword(open, "endautoescape") -> true;
 is_keyword(open, "block") -> true;
 is_keyword(open, "block") -> true;
 is_keyword(open, "endblock") -> true;
 is_keyword(open, "endblock") -> true;
+is_keyword(open, "language") -> true;
+is_keyword(open, "endlanguage") -> true;
 is_keyword(open, "comment") -> true;
 is_keyword(open, "comment") -> true;
 is_keyword(open, "endcomment") -> true;
 is_keyword(open, "endcomment") -> true;
 is_keyword(open, "cycle") -> true;
 is_keyword(open, "cycle") -> true;

+ 2 - 0
src/erlydtl_scanner.slex

@@ -332,6 +332,8 @@ form \
   is_keyword(open, "endautoescape") -> true; \
   is_keyword(open, "endautoescape") -> true; \
   is_keyword(open, "block") -> true; \
   is_keyword(open, "block") -> true; \
   is_keyword(open, "endblock") -> true; \
   is_keyword(open, "endblock") -> true; \
+  is_keyword(open, "language") -> true; \
+  is_keyword(open, "endlanguage") -> true; \
   is_keyword(open, "comment") -> true; \
   is_keyword(open, "comment") -> true; \
   is_keyword(open, "endcomment") -> true; \
   is_keyword(open, "endcomment") -> true; \
   is_keyword(open, "cycle") -> true; \
   is_keyword(open, "cycle") -> true; \

+ 6 - 0
test/erlydtl_test_defs.erl

@@ -1547,6 +1547,12 @@ all_test_defs() ->
         [{locale, default}, {translation_fun, fun () -> fun lists:reverse/1 end}],
         [{locale, default}, {translation_fun, fun () -> fun lists:reverse/1 end}],
         <<"oof">>}
         <<"oof">>}
       ]},
       ]},
+     {"language",
+      [{"override locale",
+        <<"{% trans 'foo' %}{% language 'other' %}{% trans 'foo' %}{% endlanguage %}">>,
+        [], [{locale, <<"default">>}, {translation_fun, fun ("foo", <<"default">>) -> "1"; ("foo", <<"other">>) -> "2"; (A, B) -> [A, B] end}],
+        <<"12">>}
+      ]},
      {"verbatim",
      {"verbatim",
       [{"Plain verbatim",
       [{"Plain verbatim",
         <<"{% verbatim %}{{ oh no{% foobar %}{% endverbatim %}">>, [],
         <<"{% verbatim %}{{ oh no{% foobar %}{% endverbatim %}">>, [],