Просмотр исходного кода

Compile to binaries by default

Evan Miller 13 лет назад
Родитель
Сommit
c17a7703fc

+ 3 - 0
README.markdown

@@ -87,6 +87,9 @@ specified in `blocktrans_locales`. The fun should take the form:
 * `blocktrans_locales` - A list of locales to be passed to `blocktrans_fun`.
 Defaults to [].
 
+* `binary_strings` - Whether to compile strings as binary terms (rather than
+lists). Defaults to `true`.
+
 
 Helper compilation
 ------------------

+ 64 - 46
src/erlydtl_compiler.erl

@@ -54,6 +54,7 @@
     reader = {file, read_file},
     module = [],
     compiler_options = [verbose, report_errors],
+    binary_strings = true,
     force_recompile = false,
     locale = none,
     is_compiling_dir = false}).
@@ -183,7 +184,8 @@ compile_to_binary(File, DjangoParseTree, Context, CheckSum) ->
         {{BodyAst, BodyInfo}, BodyTreeWalker} ->
             try custom_tags_ast(BodyInfo#ast_info.custom_tags, Context, BodyTreeWalker) of
                 {{CustomTagsAst, CustomTagsInfo}, _} ->
-                    Forms = forms(File, Context#dtl_context.module, {BodyAst, BodyInfo}, {CustomTagsAst, CustomTagsInfo}, CheckSum), 
+                    Forms = forms(File, Context#dtl_context.module, {BodyAst, BodyInfo}, 
+                        {CustomTagsAst, CustomTagsInfo}, Context#dtl_context.binary_strings, CheckSum), 
                     compile_forms_and_reload(File, Forms, Context#dtl_context.compiler_options)
             catch 
                 throw:Error -> Error
@@ -221,6 +223,7 @@ init_dtl_context(File, Module, Options) ->
         vars = proplists:get_value(vars, Options, Ctx#dtl_context.vars), 
         reader = proplists:get_value(reader, Options, Ctx#dtl_context.reader),
         compiler_options = proplists:get_value(compiler_options, Options, Ctx#dtl_context.compiler_options),
+        binary_strings = proplists:get_value(binary_strings, Options, Ctx#dtl_context.binary_strings),
         force_recompile = proplists:get_value(force_recompile, Options, Ctx#dtl_context.force_recompile),
         locale = proplists:get_value(locale, Options, Ctx#dtl_context.locale),
         is_compiling_dir = false}.
@@ -240,6 +243,7 @@ init_dtl_context_dir(Dir, Module, Options) ->
         vars = proplists:get_value(vars, Options, Ctx#dtl_context.vars), 
         reader = proplists:get_value(reader, Options, Ctx#dtl_context.reader),
         compiler_options = proplists:get_value(compiler_options, Options, Ctx#dtl_context.compiler_options),
+        binary_strings = proplists:get_value(binary_strings, Options, Ctx#dtl_context.binary_strings),
         force_recompile = proplists:get_value(force_recompile, Options, Ctx#dtl_context.force_recompile),
         locale = proplists:get_value(locale, Options, Ctx#dtl_context.locale),
         is_compiling_dir = true}.
@@ -358,7 +362,9 @@ dependencies_function(Dependencies) ->
 translatable_strings_function(TranslatableStrings) ->
         erl_syntax:function(
         erl_syntax:atom(translatable_strings), [erl_syntax:clause([], none,
-                [erl_syntax:list(lists:map(fun(String) -> erl_syntax:string(String) end,
+                [erl_syntax:list(lists:map(fun(String) -> 
+                                    erl_syntax:string(String) 
+                            end,
                             TranslatableStrings))])]).
 
 custom_forms(Dir, Module, Functions, AstInfo) ->
@@ -383,7 +389,7 @@ custom_forms(Dir, Module, Functions, AstInfo) ->
     [erl_syntax:revert(X) || X <- [ModuleAst, ExportAst, SourceFunctionAst, DependenciesFunctionAst, TranslatableStringsFunctionAst
             | FunctionAsts] ++ AstInfo#ast_info.pre_render_asts].
 
-forms(File, Module, {BodyAst, BodyInfo}, {CustomTagsFunctionAst, CustomTagsInfo}, CheckSum) ->
+forms(File, Module, {BodyAst, BodyInfo}, {CustomTagsFunctionAst, CustomTagsInfo}, BinaryStrings, CheckSum) ->
     MergedInfo = merge_info(BodyInfo, CustomTagsInfo),
     Render0FunctionAst = erl_syntax:function(erl_syntax:atom(render),
         [erl_syntax:clause([], none, [erl_syntax:application(none, 
@@ -430,7 +436,7 @@ forms(File, Module, {BodyAst, BodyInfo}, {CustomTagsFunctionAst, CustomTagsInfo}
     BodyAstTmp = erl_syntax:application(
                     erl_syntax:atom(erlydtl_runtime),
                     erl_syntax:atom(stringify_final),
-                    [BodyAst]),
+                    [BodyAst, erl_syntax:atom(BinaryStrings)]),
 
     RenderInternalFunctionAst = erl_syntax:function(
         erl_syntax:atom(render_internal), 
@@ -550,12 +556,12 @@ body_ast(DjangoParseTree, Context, TreeWalker) ->
             ({'ssi_parsed', {string_literal, _, FileName}}, TreeWalkerAcc) ->
                 include_ast(unescape_string_literal(FileName), [], Context#dtl_context.local_scopes, Context, TreeWalkerAcc);
             ({'string', _Pos, String}, TreeWalkerAcc) -> 
-                string_ast(String, TreeWalkerAcc);
+                string_ast(String, Context, TreeWalkerAcc);
             ({'tag', {'identifier', _, Name}, Args}, TreeWalkerAcc) ->
                 tag_ast(Name, Args, Context, TreeWalkerAcc);            
             ({'templatetag', {_, _, TagName}}, TreeWalkerAcc) ->
                 templatetag_ast(TagName, Context, TreeWalkerAcc);
-	    ({'trans', Value}, TreeWalkerAcc) ->
+            ({'trans', Value}, TreeWalkerAcc) ->
                 translated_ast(Value, Context, TreeWalkerAcc);
             ({'widthratio', Numerator, Denominator, Scale}, TreeWalkerAcc) ->
                 widthratio_ast(Numerator, Denominator, Scale, Context, TreeWalkerAcc);
@@ -610,10 +616,10 @@ value_ast(ValueToken, AsString, Context, TreeWalker) ->
                                          [Value1Ast, Value2Ast]),
             {{Ast, merge_info(InfoValue1,InfoValue2)}, TreeWalker2};
         {'string_literal', _Pos, String} ->
-            {{erl_syntax:string(unescape_string_literal(String)), #ast_info{}}, TreeWalker};
+            string_ast(unescape_string_literal(String), Context, TreeWalker);
         {'number_literal', _Pos, Number} ->
             case AsString of
-                true  -> string_ast(Number, TreeWalker);
+                true  -> string_ast(Number, Context, TreeWalker);
                 false -> {{erl_syntax:integer(list_to_integer(Number)), #ast_info{}}, TreeWalker}
             end;
         {'apply_filter', Variable, Filter} ->
@@ -697,7 +703,7 @@ translated_ast({string_literal, _, String}, Context, TreeWalker) ->
         none -> NewStr;
         Locale -> erlydtl_i18n:translate(NewStr,Locale)
     end,
-    translated_ast2(erl_syntax:string(NewStr), erl_syntax:string(DefaultString),
+    translated_ast2(erl_syntax:string(NewStr), erl_syntax:string(DefaultString), 
         #ast_info{translatable_strings = [NewStr]}, TreeWalker);
 translated_ast(ValueToken, Context, TreeWalker) ->
     {{Ast, Info}, TreeWalker1} = value_ast(ValueToken, true, Context, TreeWalker),
@@ -711,22 +717,22 @@ translated_ast2(NewStrAst, DefaultStringAst, AstInfo, TreeWalker) ->
     {{StringLookupAst, AstInfo}, TreeWalker}.
 
 % Completely unnecessary in ErlyDTL (use {{ "{%" }} etc), but implemented for compatibility.
-templatetag_ast('openblock', _Context, TreeWalker) ->
-    {{erl_syntax:string("{%"), #ast_info{}}, TreeWalker};
-templatetag_ast('closeblock', _Context, TreeWalker) ->
-    {{erl_syntax:string("%}"), #ast_info{}}, TreeWalker};
-templatetag_ast('openvariable', _Context, TreeWalker) ->
-    {{erl_syntax:string("{{"), #ast_info{}}, TreeWalker};
-templatetag_ast('closevariable', _Context, TreeWalker) ->
-    {{erl_syntax:string("}}"), #ast_info{}}, TreeWalker};
-templatetag_ast('openbrace', _Context, TreeWalker) ->
-    {{erl_syntax:string("{"), #ast_info{}}, TreeWalker};
-templatetag_ast('closebrace', _Context, TreeWalker) ->
-    {{erl_syntax:string("}"), #ast_info{}}, TreeWalker};
-templatetag_ast('opencomment', _Context, TreeWalker) ->
-    {{erl_syntax:string("{#"), #ast_info{}}, TreeWalker};
-templatetag_ast('closecomment', _Context, TreeWalker) ->
-    {{erl_syntax:string("#}"), #ast_info{}}, TreeWalker}.
+templatetag_ast('openblock', Context, TreeWalker) ->
+    string_ast("{%", Context, TreeWalker);
+templatetag_ast('closeblock', Context, TreeWalker) ->
+    string_ast("%}", Context, TreeWalker);
+templatetag_ast('openvariable', Context, TreeWalker) ->
+    string_ast("{{", Context, TreeWalker);
+templatetag_ast('closevariable', Context, TreeWalker) ->
+    string_ast("}}", Context, TreeWalker);
+templatetag_ast('openbrace', Context, TreeWalker) ->
+    string_ast("{", Context, TreeWalker);
+templatetag_ast('closebrace', Context, TreeWalker) ->
+    string_ast("}", Context, TreeWalker);
+templatetag_ast('opencomment', Context, TreeWalker) ->
+    string_ast("{#", Context, TreeWalker);
+templatetag_ast('closecomment', Context, TreeWalker) ->
+    string_ast("#}", Context, TreeWalker).
 
 
 widthratio_ast(Numerator, Denominator, Scale, Context, TreeWalker) ->
@@ -739,10 +745,13 @@ widthratio_ast(Numerator, Denominator, Scale, Context, TreeWalker) ->
                 [NumAst, DenAst, ScaleAst])), merge_info(ScaleInfo, merge_info(NumInfo, DenInfo))},
         TreeWalker3}.
 
+binary_string(String) ->
+    erl_syntax:binary([erl_syntax:binary_field(erl_syntax:integer(X)) || X <- String]).
 
-string_ast(String, TreeWalker) ->
+string_ast(String, #dtl_context{ binary_strings = true }, TreeWalker) ->
+    {{binary_string(String), #ast_info{}}, TreeWalker};
+string_ast(String, #dtl_context{ binary_strings = false }, TreeWalker) ->
     {{erl_syntax:string(String), #ast_info{}}, TreeWalker}. %% less verbose AST, better for development and debugging
-    % {{erl_syntax:binary([erl_syntax:binary_field(erl_syntax:integer(X)) || X <- String]), #ast_info{}}, TreeWalker}.       
 
 
 include_ast(File, ArgList, Scopes, Context, TreeWalker) ->
@@ -788,8 +797,8 @@ filter_tag_ast(FilterList, Contents, Context, TreeWalker) ->
                 {Ast, AstInfo} = filter_ast1(Filter, AstAcc, Context),
                 {{Ast, merge_info(InfoAcc, AstInfo)}, TreeWalkerAcc}
         end, {{erl_syntax:application(
-                    erl_syntax:atom(lists),
-                    erl_syntax:atom(flatten),
+                    erl_syntax:atom(erlang),
+                    erl_syntax:atom(iolist_to_binary),
                     [InnerAst]), Info}, TreeWalker1}, FilterList),
 
     EscapedAst = case search_for_escape_filter(lists:reverse(FilterList), Context) of
@@ -852,7 +861,9 @@ filter_ast_noescape(Variable, Filter, Context, TreeWalker) ->
     {VarValue, Info2} = filter_ast1(Filter, VariableAst, Context),
     {{VarValue, merge_info(Info1, Info2)}, TreeWalker2}.
 
-filter_ast1([{identifier, _, Name}, {string_literal, _, ArgName}], VariableAst, _Context) ->
+filter_ast1([{identifier, _, Name}, {string_literal, _, ArgName}], VariableAst, #dtl_context{ binary_strings = true }) ->
+    filter_ast2(Name, VariableAst, [binary_string(unescape_string_literal(ArgName))], []);
+filter_ast1([{identifier, _, Name}, {string_literal, _, ArgName}], VariableAst, #dtl_context{ binary_strings = false }) ->
     filter_ast2(Name, VariableAst, [erl_syntax:string(unescape_string_literal(ArgName))], []);
 filter_ast1([{identifier, _, Name}, {number_literal, _, ArgName}], VariableAst, _Context) ->
     filter_ast2(Name, VariableAst, [erl_syntax:integer(list_to_integer(ArgName))], []);
@@ -1016,38 +1027,44 @@ for_loop_ast(IteratorList, LoopValue, Contents, {EmptyContentsAst, EmptyContents
             }, TreeWalker2}.
 
 cycle_ast(Names, Context, TreeWalker) ->
-    NamesTuple = lists:map(fun({string_literal, _, Str}) ->
-                                   erl_syntax:string(unescape_string_literal(Str));
-                              ({variable, _}=Var) ->
-                                   {V, _} = resolve_variable_ast(Var, Context),
-                                   V;
-                              ({number_literal, _, Num}) ->
-                                   format(erl_syntax:integer(Num), Context, TreeWalker);
-                              (_) ->
-                                   []
-                           end, Names),
+    NamesTuple = lists:map(fun
+            ({string_literal, _, Str}) ->
+                {{S, _}, _} = string_ast(unescape_string_literal(Str), Context, TreeWalker),
+                S;
+            ({variable, _}=Var) ->
+                {V, _} = resolve_variable_ast(Var, Context),
+                V;
+            ({number_literal, _, Num}) ->
+                format(erl_syntax:integer(Num), Context, TreeWalker);
+            (_) ->
+                []
+        end, Names),
     {{erl_syntax:application(
         erl_syntax:atom('erlydtl_runtime'), erl_syntax:atom('cycle'),
         [erl_syntax:tuple(NamesTuple), erl_syntax:variable("Counters")]), #ast_info{}}, TreeWalker}.
 
 %% Older Django templates treat cycle with comma-delimited elements as strings
-cycle_compat_ast(Names, _Context, TreeWalker) ->
-    NamesTuple = [erl_syntax:string(X) || {identifier, _, X} <- Names],
+cycle_compat_ast(Names, Context, TreeWalker) ->
+    NamesTuple = lists:map(fun
+            ({identifier, _, X}) ->
+                    {{S, _}, _} = string_ast(X, Context, TreeWalker),
+                    S
+            end, Names),
     {{erl_syntax:application(
         erl_syntax:atom('erlydtl_runtime'), erl_syntax:atom('cycle'),
         [erl_syntax:tuple(NamesTuple), erl_syntax:variable("Counters")]), #ast_info{}}, TreeWalker}.
 
-now_ast(FormatString, _Context, TreeWalker) ->
+now_ast(FormatString, Context, TreeWalker) ->
     % Note: we can't use unescape_string_literal here
     % because we want to allow escaping in the format string.
     % We only want to remove the surrounding escapes,
     % i.e. \"foo\" becomes "foo"
     UnescapeOuter = string:strip(FormatString, both, 34),
+    {{StringAst, Info}, TreeWalker1} = string_ast(UnescapeOuter, Context, TreeWalker),
     {{erl_syntax:application(
         erl_syntax:atom(erlydtl_dateformat),
         erl_syntax:atom(format),
-        [erl_syntax:string(UnescapeOuter)]),
-        #ast_info{}}, TreeWalker}.
+        [StringAst]), Info}, TreeWalker1}.
 
 spaceless_ast(Contents, Context, TreeWalker) ->
     {{Ast, Info}, TreeWalker1} = body_ast(Contents, Context, TreeWalker),
@@ -1088,7 +1105,8 @@ full_path(File, DocRoot) ->
 tag_ast(Name, Args, Context, TreeWalker) ->
     {InterpretedArgs, AstInfo} = lists:mapfoldl(fun
             ({{identifier, _, Key}, {string_literal, _, Value}}, AstInfoAcc) ->
-                {erl_syntax:tuple([erl_syntax:string(Key), erl_syntax:string(unescape_string_literal(Value))]), AstInfoAcc};
+                {{StringAst, StringAstInfo}, _} = string_ast(unescape_string_literal(Value), Context, TreeWalker),
+                {erl_syntax:tuple([erl_syntax:string(Key), StringAst]), merge_info(StringAstInfo, AstInfoAcc)};
             ({{identifier, _, Key}, {trans, StringLiteral}}, AstInfoAcc) ->
                 {{TransAst, TransAstInfo}, _} = translated_ast(StringLiteral, Context, TreeWalker),
                 {erl_syntax:tuple([erl_syntax:string(Key), TransAst]), merge_info(TransAstInfo, AstInfoAcc)};

+ 20 - 4
src/erlydtl_filters.erl

@@ -182,6 +182,8 @@ center(Input, Number) when is_list(Input) ->
     string:centre(Input, Number).
  
 %% @doc Removes all values of arg from the given string.
+cut(Input, Arg) when is_binary(Arg) ->
+    cut(Input, binary_to_list(Arg));
 cut(Input, Arg) when is_binary(Input) ->
     cut(binary_to_list(Input), Arg);
 cut(Input, [Char]) when is_list(Input) ->
@@ -231,6 +233,8 @@ divisibleby(Input, Divisor) when is_binary(Input) ->
     divisibleby(binary_to_list(Input), Divisor);
 divisibleby(Input, Divisor) when is_list(Input) ->
     divisibleby(list_to_integer(Input), Divisor);
+divisibleby(Input, Divisor) when is_binary(Divisor) ->
+    divisibleby(Input, binary_to_list(Divisor));
 divisibleby(Input, Divisor) when is_list(Divisor) ->
     divisibleby(Input, list_to_integer(Divisor));
 divisibleby(Input, Divisor) when is_integer(Input), is_integer(Divisor) ->
@@ -302,7 +306,9 @@ round(Number, Precision) ->
 force_escape(Input) when is_list(Input) ->
     escape(Input, []);
 force_escape(Input) when is_binary(Input) ->
-    escape(Input, 0).
+    escape(Input, 0);
+force_escape(Input) ->
+    Input.
 
 format_integer(Input) when is_integer(Input) ->
     integer_to_list(Input);
@@ -323,6 +329,8 @@ get_digit(Input, Digit) when is_binary(Input) ->
     get_digit(binary_to_list(Input), Digit);
 get_digit(Input, Digit) when is_integer(Input) ->
     get_digit(integer_to_list(Input), Digit);
+get_digit(Input, Digit) when is_binary(Digit) ->
+    get_digit(Input, binary_to_list(Digit));
 get_digit(Input, Digit) when is_list(Digit) ->
     get_digit(Input, list_to_integer(Digit));
 get_digit(Input, Digit) when Digit > erlang:length(Input) ->
@@ -488,8 +496,10 @@ random_range(Start, End) when End >= Start ->
     Num = Rand + Start,
     lists:flatten(io_lib:format("~B",[Num])).
 
-removetags(Input, Tags) when is_binary(Input), is_binary(Tags) ->
-    removetags(binary_to_list(Input), binary_to_list(Tags));
+removetags(Input, Tags) when is_binary(Input) ->
+    removetags(binary_to_list(Input), Tags);
+removetags(Input, Tags) when is_binary(Tags) ->
+    removetags(Input, binary_to_list(Tags));
 removetags(Input, Tags) ->
     TagList = string:tokens(Tags," "),
     TagListString = string:join(TagList,"|"),
@@ -514,6 +524,8 @@ slice(Input, Index) when is_list(Input) ->
 %% @doc Returns a formatted string
 stringformat(Input, Conversion) when is_binary(Input) ->
     stringformat(binary_to_list(Input), Conversion);
+stringformat(Input, Conversion) when is_binary(Conversion) ->
+    stringformat(Input, binary_to_list(Conversion));
 stringformat(Input, Conversion) ->
     ParsedConversion = re:replace(Conversion, "([\-#\+ ]?)([0-9\*]+)?(\.?)([0-9]?)([diouxXeEfFgGcrs])", "\\1 ,\\2 ,\\3 ,\\4 ,\\5 ", [{return,list}]),
     ?debugFmt("ParsedConversion: ~p~n", [ParsedConversion]),
@@ -667,6 +679,8 @@ cast_to_integer(Input) when is_integer(Input) ->
     Input;
 cast_to_integer(Input) when is_float(Input) ->
     erlang:round(Input);
+cast_to_integer(Input) when is_binary(Input) ->
+    cast_to_integer(binary_to_list(Input));
 cast_to_integer(Input) when is_list(Input)->
     case lists:member($., Input) of
         true ->
@@ -791,8 +805,10 @@ wordwrap(Input, Number) when is_list(Input) ->
     wordwrap(Input, [], [], 0, Number).
 
 %% @doc Given a string mapping values for true, false and (optionally) undefined, returns one of those strings according to the value.
-yesno(Bool, Choices) when is_binary(Choices) ->
+yesno(Bool, Choices) when is_binary(Bool) ->
     yesno_io(binary_to_list(Bool), Choices);
+yesno(Bool, Choices) when is_binary(Choices) ->
+    yesno_io(Bool, binary_to_list(Choices));
 yesno(Bool, Choices) when is_list(Choices) ->
     yesno_io(Bool, Choices).
 

+ 18 - 14
src/erlydtl_runtime.erl

@@ -52,11 +52,10 @@ fetch_value(Key, Data) ->
 
 translate(_, none, Default) ->
     Default;
-translate(String, TranslationFun, Default) when is_binary(String) ->
-    translate(binary_to_list(String), TranslationFun, Default);
 translate(String, TranslationFun, Default) when is_function(TranslationFun) ->
     case TranslationFun(String) of
         undefined -> Default;
+        <<"">> -> Default;
         "" -> Default;
         Str -> Str
     end.
@@ -154,18 +153,23 @@ is_true(V) ->
 'lt'(_, _) ->
     false.
 
-stringify_final(In) ->
-   stringify_final(In, []).
-stringify_final([], Out) ->
-   lists:reverse(Out);
-stringify_final([El | Rest], Out) when is_atom(El) ->
-   stringify_final(Rest, [atom_to_list(El) | Out]);
-stringify_final([El | Rest], Out) when is_list(El) ->
-   stringify_final(Rest, [stringify_final(El) | Out]);
-stringify_final([El | Rest], Out) when is_tuple(El) ->
-   stringify_final(Rest, [io_lib:print(El) | Out]);
-stringify_final([El | Rest], Out) ->
-   stringify_final(Rest, [El | Out]).
+stringify_final(In, BinaryStrings) ->
+    stringify_final(In, [], BinaryStrings).
+
+stringify_final([], Out, _) ->
+    lists:reverse(Out);
+stringify_final([El | Rest], Out, false = BinaryStrings) when is_atom(El) ->
+    stringify_final(Rest, [atom_to_list(El) | Out], BinaryStrings);
+stringify_final([El | Rest], Out, true = BinaryStrings) when is_atom(El) ->
+    stringify_final(Rest, [list_to_binary(atom_to_list(El)) | Out], BinaryStrings);
+stringify_final([El | Rest], Out, BinaryStrings) when is_list(El) ->
+    stringify_final(Rest, [stringify_final(El, BinaryStrings) | Out], BinaryStrings);
+stringify_final([El | Rest], Out, false = BinaryStrings) when is_tuple(El) ->
+    stringify_final(Rest, [io_lib:print(El) | Out], BinaryStrings);
+stringify_final([El | Rest], Out, true = BinaryStrings) when is_tuple(El) ->
+    stringify_final(Rest, [list_to_binary(io_lib:print(El)) | Out], BinaryStrings);
+stringify_final([El | Rest], Out, BinaryStrings) ->
+    stringify_final(Rest, [El | Out], BinaryStrings).
 
 init_counter_stats(List) ->
     init_counter_stats(List, undefined).

+ 5 - 1
src/filter_lib/erlydtl_dateformat.erl

@@ -43,6 +43,8 @@
 %
 % Format the current date/time
 %
+format(FormatString) when is_binary(FormatString) ->
+    format(binary_to_list(FormatString));
 format(FormatString) ->
     {Date, Time} = erlang:localtime(),
     replace_tags(Date, Time, FormatString).
@@ -51,8 +53,10 @@ format(FormatString) ->
 % This is the format returned by erlang:localtime()
 % and other standard date/time BIFs
 %
+format(DateTime, FormatString) when is_binary(FormatString) ->
+    format(DateTime, binary_to_list(FormatString));
 format({{_,_,_} = Date,{_,_,_} = Time}, FormatString) ->
-   replace_tags(Date, Time, FormatString);
+    replace_tags(Date, Time, FormatString);
 %
 % Format a tuple of the form {Y,M,D}
 %

+ 7 - 6
tests/src/erlydtl_unittests.erl

@@ -928,13 +928,13 @@ tests() ->
                 <<"Hello {% trans \"Hi\" %}">>, [], [{translation_fun, fun("Hi") -> "Konichiwa" end}], [],
                 <<"Hello Konichiwa">>},
             {"trans variable at run-time",
-                <<"Hello {% trans var1 %}">>, [{var1, "Hi"}], [{translation_fun, fun("Hi") -> "Konichiwa" end}], [],
+                <<"Hello {% trans var1 %}">>, [{var1, <<"Hi">>}], [{translation_fun, fun(<<"Hi">>) -> <<"Konichiwa">> end}], [],
                 <<"Hello Konichiwa">>},
             {"trans literal at run-time: No-op",
-                <<"Hello {% trans \"Hi\" noop %}">>, [], [{translation_fun, fun("Hi") -> "Konichiwa" end}], [],
+                <<"Hello {% trans \"Hi\" noop %}">>, [], [{translation_fun, fun("Hi") -> <<"Konichiwa">> end}], [],
                 <<"Hello Hi">>},
             {"trans variable at run-time: No-op",
-                <<"Hello {% trans var1 noop %}">>, [{var1, "Hi"}], [{translation_fun, fun("Hi") -> "Konichiwa" end}], [],
+                <<"Hello {% trans var1 noop %}">>, [{var1, <<"Hi">>}], [{translation_fun, fun(<<"Hi">>) -> <<"Konichiwa">> end}], [],
                 <<"Hello Hi">>}
         ]},
     {"blocktrans",
@@ -967,18 +967,19 @@ tests() ->
  
 run_tests() ->
     io:format("Running unit tests...~n"),
+    DefaultOptions = [],
     Failures = lists:foldl(
         fun({Group, Assertions}, GroupAcc) ->
                 io:format(" Test group ~p...~n", [Group]),
                 lists:foldl(fun
                         ({Name, DTL, Vars, Output}, Acc) ->
-                            process_unit_test(erlydtl:compile(DTL, erlydtl_running_test, []),
+                            process_unit_test(erlydtl:compile(DTL, erlydtl_running_test, DefaultOptions),
                                 Vars, [], Output, Acc, Group, Name);
                         ({Name, DTL, Vars, RenderOpts, Output}, Acc) ->
-                            process_unit_test(erlydtl:compile(DTL, erlydtl_running_test, []),
+                            process_unit_test(erlydtl:compile(DTL, erlydtl_running_test, DefaultOptions),
                                 Vars, RenderOpts, Output, Acc, Group, Name);
                         ({Name, DTL, Vars, RenderOpts, CompilerOpts, Output}, Acc) ->
-                            process_unit_test(erlydtl:compile(DTL, erlydtl_running_test, CompilerOpts),
+                            process_unit_test(erlydtl:compile(DTL, erlydtl_running_test, CompilerOpts ++ DefaultOptions),
                                 Vars, RenderOpts, Output, Acc, Group, Name)
                             end, GroupAcc, Assertions)
         end, [], tests()),