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

* Fix custom tags, "extends" tests
* Move custom tag files to be extension-less
* Fix reference to old emiller_* module name in auto-escape logic
* Clean up erlydtl_demo.erl to use file extension compiled into the module
* Add method render/0 to compiled templates

Evan Miller 17 лет назад
Родитель
Сommit
ba542a06c6

+ 11 - 0
demo/out/test_extends.html

@@ -0,0 +1,11 @@
+base-barstring
+
+base template
+
+replacing the base title
+
+more of base template
+
+replacing the base content - variable: test-barstring after variable 
+
+end of base template

+ 1 - 3
demo/templates/base.html

@@ -1,5 +1,3 @@
-{{ preset_base_var }}
-
 {{ base_var }}
 
 base template
@@ -10,4 +8,4 @@ more of base template
 
 {% block content %}base content{% endblock %}
 
-end of base template
+end of base template

+ 0 - 0
priv/tags/flashvideo.html → priv/tags/flashvideo


+ 0 - 0
priv/tags/menu.css → priv/tags/menu


+ 30 - 53
src/demo/erlydtl_demo.erl

@@ -46,6 +46,7 @@
 %%--------------------------------------------------------------------
 compile_all() ->
     DocRoot = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "templates"]),
+    io:format("Compiling folder: ~p~n", [DocRoot]),
     filelib:fold_files(DocRoot,
         "\.html$|\.css$",
         true,
@@ -145,63 +146,53 @@ render_all() ->
 %% @end 
 %%--------------------------------------------------------------------
 render("var" = Name) ->
-    render(Name, ".html", [{var1, "foostring1"}, {var2, "foostring2"}, {var_not_used, "foostring3"}]);
+    render(Name, [{var1, "foostring1"}, {var2, "foostring2"}, {var_not_used, "foostring3"}]);
  
 render("extends" = Name) ->
-    render(Name, ".html", [{base_var, "base-barstring"}, {test_var, "test-barstring"}]);
+    render(Name, [{base_var, "base-barstring"}, {test_var, "test-barstring"}]);
         
 render("comment" = Name) ->
-    render(Name, ".html");
+    render(Name, []);
 
 render("for" = Name) ->
-    render(Name, ".html", [{fruit_list, ["apple", "banana", "coconut"]}]);
+    render(Name, [{fruit_list, ["apple", "banana", "coconut"]}]);
             
 render("for_records" = Name) ->
     Link1 = [{name, "Amazon"}, {url, "http://amazon.com"}],
     Link2 = [{name, "Google"}, {url, "http://google.com"}],
     Link3 = [{name, "Microsoft"}, {url, "http://microsoft.com"}],
-    render(Name, ".html", [{link_list, [Link1, Link2, Link3]}]);
+    render(Name, [{link_list, [Link1, Link2, Link3]}]);
                 
 render("htmltags" = Name) ->
-    render(Name, ".html");
+    render(Name, []);
     
 render("csstags" = Name) ->
-    render(Name, ".css");
+    render(Name, []);
   
 render("var_preset" = Name) ->
-    render(Name, ".html", [{var1, "foostring1"}, {var2, "foostring2"}]);
+    render(Name, [{var1, "foostring1"}, {var2, "foostring2"}]);
  
 render("for_preset" = Name) ->
-    render(Name, ".html");
+    render(Name, []);
             
 render("for_records_preset" = Name) ->
     Link1 = [{name, "Canon"}, {url, "http://canon.com"}],
     Link2 = [{name, "Leica"}, {url, "http://leica.com"}],
     Link3 = [{name, "Nikon"}, {url, "http://nikon.com"}],
-    render(Name, ".html", [{photo_links, [Link1, Link2, Link3]}]);
+    render(Name, [{photo_links, [Link1, Link2, Link3]}]);
         
 render(Name) ->
     io:format("No such template: ~p~n",[Name]).  
                 
                 
 %%--------------------------------------------------------------------
-%% @spec (atom(), string()) -> any()
-%% @doc renders template to a file
-%% @end 
-%%--------------------------------------------------------------------
-render(Name, Ext) ->
-    OutDir = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "out"]),
-    render2(OutDir, list_to_atom("test_" ++ Name), Ext).   
-    
-
-%%--------------------------------------------------------------------
 %% @spec (atom(), string(), string()) -> any()
 %% @doc renders template to a file
 %% @end 
 %%--------------------------------------------------------------------
-render(Name, Ext, Args) ->
+render(Name, Args) ->
     OutDir = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "out"]),
-    render2(OutDir, list_to_atom("test_" ++ Name), Ext, Args).
+    render2(OutDir, list_to_atom("test_" ++ Name), Args).
             
 
 %%--------------------------------------------------------------------
@@ -229,45 +220,31 @@ preset(test_for_records_preset) ->
 %% Internal functions
 %%====================================================================
 
-render2(OutDir, Module, Ext, Arg) ->
-    case catch apply(Module, render, [Arg]) of
+render2(OutDir, Module, Arg) ->
+    case catch Module:render(Arg) of
         {ok, Val, Warnings} -> 
-            write_file(OutDir, Module, Ext, Val, Warnings);
+            write_file(OutDir, Module, Val, Warnings);
         {error, Err, Warnings} ->
             io:format("TRACE ~p:~p Errors: ~p~n",[?MODULE, ?LINE, Err]),
             io:format("TRACE ~p:~p Warnings: ~p~n",[?MODULE, ?LINE, Warnings]);
         {'EXIT', Reason} -> 
             io:format("TRACE ~p:~p ~p: render failure: ~n",[?MODULE, ?LINE, Reason]);
         Val -> %% only temporarly
-            write_file(OutDir, Module, Ext, Val, [])
+            write_file(OutDir, Module, Val, [])
     end.
     
     
-render2(OutDir, Module, Ext) ->
-    case catch Module:render() of      
-        {ok, Val, Warnings} -> 
-            write_file(OutDir, Module, Ext, Val, Warnings);
-        {error, Err, Warnings} ->
-            io:format("TRACE ~p:~p Errors: ~p~n",[?MODULE, ?LINE, Err]),
-            io:format("TRACE ~p:~p Warnings: ~p~n",[?MODULE, ?LINE, Warnings]);
-        {'EXIT', Reason} -> 
-            io:format("TRACE ~p:~p ~p: render failure: ~n",[?MODULE, ?LINE, Reason]);
-        Val -> %% only temporarly
-            write_file(OutDir, Module, Ext, Val, [])
+write_file(OutDir, Module, Val, Warnings) ->
+    case file:open(filename:join([OutDir, lists:concat([Module, ".", Module:file_extension()])]), [write]) of
+	{ok, IoDev} ->
+	    file:write(IoDev, Val),
+	    file:close(IoDev),
+	    case Warnings of
+		[] ->
+		    io:format("render success: ~p~n",[Module]);    
+		_ -> 
+		    io:format("render success: ~p - Warnings: ~p~n",[Module, Warnings])
+	    end;
+	_ ->
+	    io:format("render failure: ~p~n",[Module])
     end.
-
-
-write_file(OutDir, Module, Ext, Val, Warnings) ->
-    case file:open(filename:join([OutDir, lists:concat([Module, Ext])]), [write]) of
-		{ok, IoDev} ->
-		    file:write(IoDev, Val),
-		    file:close(IoDev),
-		    case Warnings of
-		        [] ->
-		            io:format("render success: ~p~n",[Module]);    
-		        _ -> 
-		            io:format("render success: ~p - Warnings: ~p~n",[Module, Warnings])
-		    end;
-		_ ->
-		    io:format("render failure: ~p~n",[Module])
-	end.

+ 43 - 35
src/erlydtl/erlydtl_compiler.erl

@@ -56,37 +56,44 @@ compile(File, DocRoot, Module, Function) ->
 compile(File, DocRoot, Module, Function, OutDir) ->
     case parse(File) of
         {ok, DjangoAst} ->
-        RenderFunctionAst = erl_syntax:function(
-            erl_syntax:atom(Function), 
-            [erl_syntax:clause([erl_syntax:variable("Variables")], none, 
-            [body_ast(DjangoAst, #dtl_context{doc_root = DocRoot, parse_trail = [File]})])]),
-        ExtensionFunctionAst = erl_syntax:function(
-            erl_syntax:atom(file_extension),
-            [erl_syntax:clause([], none, [erl_syntax:string(file_extension(File))])]),
-        ModuleAst  = erl_syntax:attribute(erl_syntax:atom(module), [erl_syntax:atom(Module)]),
-        CompileAst = erl_syntax:attribute(erl_syntax:atom(compile), [erl_syntax:atom("export_all")]),
+            Render1FunctionAst = erl_syntax:function(
+                erl_syntax:atom(Function), 
+                [erl_syntax:clause([erl_syntax:variable("Variables")], none, 
+                        [body_ast(DjangoAst, #dtl_context{doc_root = DocRoot, parse_trail = [File]})])]),
+            Render0FunctionAst = erl_syntax:function(
+                erl_syntax:atom(Function),
+                [erl_syntax:clause([], none, 
+                        [erl_syntax:application(erl_syntax:atom(Module), erl_syntax:atom(Function),
+                                [erl_syntax:list([])])]
+                    )]),
+            ExtensionFunctionAst = erl_syntax:function(
+                erl_syntax:atom(file_extension),
+                [erl_syntax:clause([], none, [erl_syntax:string(file_extension(File))])]),
+            ModuleAst  = erl_syntax:attribute(erl_syntax:atom(module), [erl_syntax:atom(Module)]),
+            CompileAst = erl_syntax:attribute(erl_syntax:atom(compile), [erl_syntax:atom("export_all")]),
 
-        Forms = [erl_syntax:revert(X) || X <- [ModuleAst, CompileAst, ExtensionFunctionAst, RenderFunctionAst]],
+            Forms = [erl_syntax:revert(X) || X <- [ModuleAst, CompileAst, ExtensionFunctionAst, 
+                    Render0FunctionAst, Render1FunctionAst]],
 
-        case compile:forms(Forms) of
-            {ok, Module1, Bin} ->       
-            Path = filename:join([OutDir, atom_to_list(Module1) ++ ".beam"]),
-            case file:write_file(Path, Bin) of
-                ok ->
-                code:purge(Module1),
-                case code:load_binary(Module1, atom_to_list(Module1) ++ ".erl", Bin) of
-                    {module, _} -> ok;
-                _ -> {error, "code reload failed"}
+            case compile:forms(Forms) of
+                {ok, Module1, Bin} ->       
+                Path = filename:join([OutDir, atom_to_list(Module1) ++ ".beam"]),
+                case file:write_file(Path, Bin) of
+                    ok ->
+                    code:purge(Module1),
+                    case code:load_binary(Module1, atom_to_list(Module1) ++ ".erl", Bin) of
+                        {module, _} -> ok;
+                    _ -> {error, "code reload failed"}
+                    end;
+                _ ->
+                    {error, "beam generation failed"}
                 end;
             _ ->
-                {error, "beam generation failed"}
+                {error, "compilation failed"}
             end;
-        _ ->
-            {error, "compilation failed"}
-        end;
-    Error ->
-        Error
-    end.
+        Error ->
+            Error
+        end.
 
         
 scan(File) ->
@@ -251,10 +258,10 @@ resolve_variable_name_ast(VarName, Context) ->
     end,
     case Context#dtl_context.auto_escape of
         on ->
-        erl_syntax:application(erl_syntax:atom(emiller_filters), erl_syntax:atom(force_escape),
-            [VarValue1]);
-    _ ->
-        VarValue1
+            erl_syntax:application(erl_syntax:atom(erlydtl_filters), erl_syntax:atom(force_escape),
+                [VarValue1]);
+        _ ->
+            VarValue1
     end.
 
 ifelse_ast(Variable, IfContentsAst, ElseContentsAst, Context) ->
@@ -303,12 +310,13 @@ tag_ast(Name, Args, Context) ->
         ({{identifier, _, Key}, {variable, Value}}) ->
             {list_to_atom(Key), resolve_variable_ast(Value, Context)}
         end, Args),
-    case parse(filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", Name])) of
+    Source = filename:join([erlydtl_deps:get_base_dir(), "priv", "tags", Name]),
+    case parse(Source) of
         {ok, TagAst} ->
-        body_ast(TagAst, Context#dtl_context{
-            local_scopes = [ InterpretedArgs | Context#dtl_context.local_scopes ]});
-    _ ->
-        {error, Name, "Loading tag source failed"}
+	    body_ast(TagAst, Context#dtl_context{
+		    local_scopes = [ InterpretedArgs | Context#dtl_context.local_scopes ]});
+	_ ->
+	    {error, Name, "Loading tag source failed: " ++ Source}
     end.
 
 unescape_string_literal(String) ->