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

bug-fixes (now blocks can contain variables as well)

Roberto Saccon 17 лет назад
Родитель
Сommit
afbb1cdeb8

+ 2 - 2
demo/out/test_extend.html

@@ -1,4 +1,4 @@
-blastring
+bar1string
 
 base template
 
@@ -6,6 +6,6 @@ replacing the base title
 
 more of base template
 
-replacing the base content
+replacing the base content - variable: bar2string after variable 
 
 end of base template

+ 1 - 1
demo/templates/test_extend.html

@@ -1,3 +1,3 @@
 {% extends "base.html" %}
 {% block title %}replacing the base title{% endblock %}
-{% block content %}replacing the base content{% endblock %}
+{% block content %}replacing the base content - variable: {{ another_variable }} after variable {% endblock %}

+ 4 - 4
src/demo/erlydtl_demo.erl

@@ -63,8 +63,8 @@ compile_templates() ->
 %%--------------------------------------------------------------------
 render_html() ->
     OutDir = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "out"]),
-    render(OutDir, test_variable, ".html", "foostring"),
-    render(OutDir, test_extend, ".html", "blastring"),
+    render(OutDir, test_variable, ".html", ["foostring"]),
+    render(OutDir, test_extend, ".html", ["bar1string", "bar2string"]),
     render(OutDir, test_comment, ".html").
 
               
@@ -72,8 +72,8 @@ render_html() ->
 %% Internal functions
 %%====================================================================
 
-render(OutDir, Module, Ext, Var) ->
-    case catch Module:render(Var) of
+render(OutDir, Module, Ext, Args) ->
+    case catch apply(Module, render, Args) of
         {'EXIT', Reason} -> 
             io:format("TRACE ~p:~p ~p: rendering failure: ~n",[?MODULE, ?LINE, Reason]);
         Val -> 

+ 33 - 31
src/erlydtl/erlydtl.erl

@@ -30,7 +30,7 @@
 %%%
 %%% @since 2007-11-17 by Roberto Saccon
 %%%-------------------------------------------------------------------
--module(erlydtl_api).
+-module(erlydtl).
 -author('rsaccon@gmail.com').
 
 %% API
@@ -94,18 +94,15 @@ parse(File) ->
 
 compile_reload_ast([H | T], ModuleName, FunctionName, RelDir) ->
     {List, Args} = case transl(H, T, [], [], RelDir) of
-		               {regular, List0, Args0} ->
-		                   io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, regualar]),
-			               {[inplace_block(X) ||  X <- List0], Args0};
-		               {inherited, List0, Arg0} ->
-		                   io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, inherited]),
-			               {List0, Arg0}
-		           end,    
-		           io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE,  {List, Args}]),
+	    {regular, List0, Args0} ->
+		    {[inplace_block(X) ||  X <- List0], Args0};
+		{inherited, List0, Arg0} ->
+			{List0, Arg0}
+	end,    	           
     Args2 = lists:reverse([{var, 1, Val} || {Val, _} <- Args]),  
     Cons = list_fold(lists:reverse(List)),                           
     Ast2 = {function, 1, list_to_atom(FunctionName), length(Args2),
-            [{clause, 1, Args2, [], [Cons]}]},
+        [{clause, 1, Args2, [], [Cons]}]},
     Ac = erlydtl_tools:create_module(Ast2 , ModuleName),    
     case compile:forms(Ac) of
         {ok, Module, Bin} ->
@@ -126,23 +123,28 @@ list_fold([E1, E2]) ->
     {cons, 1, E2, E1};           
 list_fold([E1, E2 | Tail]) ->
     lists:foldl(fun(X, T) -> 
-                    {cons, 1, X, T}
-                end, {cons, 1, E2, E1}, Tail).                       
+        {cons, 1, X, T}
+    end, {cons, 1, E2, E1}, Tail).                       
 
 
 transl(nil, [{extends, _, Name}], Out, Args, RelDir) -> 
     case parse(filename:join([RelDir, Name])) of
-           {ok, ParentAst} ->
-			   [H|T]=ParentAst,
-			   {_, List, Args1} = transl(H, T, [], [], RelDir),
-		       {inherited, [replace_block(X, Out) ||  X <- List], Args1};
-	       {error, Msg} ->
-	           io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
-	           io:format("TRACE ~p:~p Parent Parser failure: ~p~n",[?MODULE, ?LINE, Name]),
-		       {regular, Out, Args}			
+        {ok, ParentAst} ->
+		    [H|T]=ParentAst,
+			{_, List, Args1} = transl(H, T, [], [], RelDir),			 
+			{List3, Args3} = lists:foldl(fun(X, {List2, Args2}) -> 
+                {List4, Args4} = replace_block(X, Out, Args2),            
+                {[List4 | List2], Args4}
+            end, {[], Args1}, List),		   
+		    {inherited, lists:reverse(lists:flatten([List3])), lists:flatten(Args3)};
+	    {error, Msg} ->
+	         io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
+	         io:format("TRACE ~p:~p Parent Parser failure: ~p~n",[?MODULE, ?LINE, Name]),
+		     {regular, Out, Args}			
     end;
 	
 transl(nil, [{var, L, Val}], Out, Args, _) ->
+     io:format("TRACE ~p:~p nil ~p~n",[?MODULE, ?LINE, {Val, Args}]),
     case lists:keysearch(Val, 2, Args) of
         false ->
             Key = list_to_atom(lists:concat(["A", length(Args) + 1])),
@@ -157,9 +159,11 @@ transl(nil, [Token], Out, Args, _) ->
 transl([H | T], [{var, L, Val}], Out, Args, DocRoot) ->
     case lists:keysearch(Val, 2, Args) of
         false ->
+                io:format("TRACE ~p:~p normal_not_found ~p~n",[?MODULE, ?LINE, {Val, Args}]),              
             Key = list_to_atom(lists:concat(["A", length(Args) + 1])),
             transl(H, T, [{var, L, Key} | Out], [{Key, Val} | Args], DocRoot);
         {value, {Key, _}} ->  
+                   io:format("TRACE ~p:~p normal_found ~p~n",[?MODULE, ?LINE, {Val, Key, Args}]),
             transl(H, T, [{var, L, Key} | Out], Args, DocRoot)
 	end;	 
 	
@@ -167,21 +171,19 @@ transl([H | T], [Token], Out, Args, DocRoot) ->
     transl(H, T, [Token | Out], Args, DocRoot).
 
 
-replace_block({block, Name, [nil, Str1]}, List) ->
+replace_block({block, Name, [nil, Val]}, List, Args) ->
 	case lists:keysearch(Name, 2, List) of
 		false -> 
-			Str1;
-		{value, {_, _, [nil, Str2]}} ->  
-			Str2
+			{Val, Args};
+		{value, {_, _, [H | T]}} ->  
+		    {_, List2, Args2} = transl(H, T, [], Args, undefined),
+		    {lists:reverse(List2), Args2} 
  	end;
-replace_block(Other, _) ->	
-	Other.
-
+replace_block(Other, _, Args) ->	
+	{Other, Args}.
+    
 	
 inplace_block({block, _, [nil, Str]}) ->
 	Str;
 inplace_block(Other) ->	
-	Other.
-	
-	
-
+	Other.

+ 0 - 187
src/erlydtl/erlydtl_api.erl

@@ -1,187 +0,0 @@
-%%%-------------------------------------------------------------------
-%%% File:      erlydtl.erl
-%%% @author    Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
-%%% @copyright 2007 Roberto Saccon
-%%% @doc  
-%%% API for compiling ErlyDTL templeates
-%%% @end  
-%%%
-%%% The MIT License
-%%%
-%%% Copyright (c) 2007 Roberto Saccon
-%%%
-%%% Permission is hereby granted, free of charge, to any person obtaining a copy
-%%% of this software and associated documentation files (the "Software"), to deal
-%%% in the Software without restriction, including without limitation the rights
-%%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-%%% copies of the Software, and to permit persons to whom the Software is
-%%% furnished to do so, subject to the following conditions:
-%%%
-%%% The above copyright notice and this permission notice shall be included in
-%%% all copies or substantial portions of the Software.
-%%%
-%%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-%%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-%%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-%%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-%%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-%%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-%%% THE SOFTWARE.
-%%%
-%%% @since 2007-11-17 by Roberto Saccon
-%%%-------------------------------------------------------------------
--module(erlydtl).
--author('rsaccon@gmail.com').
-
-%% API
--export([compile/3, compile/4]).
-
-%%--------------------------------------------------------------------
-%% @spec (File:string(), ModuleName:string(), DocRoot:string()) -> 
-%%     {Ok::atom, Ast::tuple() | {Error::atom(), Msg:string()}
-%% @doc compiles a template to a beam file
-%% @end 
-%%--------------------------------------------------------------------
-compile(File, ModuleName, DocRoot) ->
-    compile(File, ModuleName, DocRoot, "render").
-    
-
-%%--------------------------------------------------------------------
-%% @spec (File:string(), ModuleName:string(), DocRoot:string(), FunctionName:atom()) -> 
-%%     {Ok::atom, Ast::tuple() | {Error::atom(), Msg:string()}
-%% @doc compiles a template to a beam file
-%% @end 
-%%--------------------------------------------------------------------
-compile(File, ModuleName, DocRoot, FunctionName) ->   
-    case parse(File) of
-        {ok, Ast} ->
-			RelDir = rel_dir(filename:dirname(File), DocRoot),
-            compile_reload_ast(Ast, ModuleName, FunctionName, RelDir);
-        {error, Msg} = Err ->
-            io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, File ++ " Parser failure:"]),
-            io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
-            Err
-	end.
-
-
-%%====================================================================
-%% Internal functions
-%%====================================================================
-
-rel_dir(Dir, DocRoot) when Dir =:= DocRoot ->
-    DocRoot;
-rel_dir(Dir, DocRoot) ->
-    RelFile = string:substr(Dir, length(DocRoot)+2),
-    filename:join([DocRoot, RelFile]).
-
-
-parse(File) ->
-	case file:read_file(File) of
-		{ok, B} ->
-	        case erlydtl_scanner:scan(binary_to_list(B)) of
-	            {ok, Tokens} ->
-	                erlydtl_parser:parse(Tokens);
-	            Err ->
-	                io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, File ++ " Scanner failure:"]),
-	                io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Err]),
-	                Err
-	        end;
-	    Err ->
-	        io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, "File read error"]),
-	        Err   
-	end.
-	
-
-compile_reload_ast([H | T], ModuleName, FunctionName, RelDir) ->
-    {List, Args} = case transl(H, T, [], [], RelDir) of
-		               {regular, List0, Args0} ->
-		                   io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, regualar]),
-			               {[inplace_block(X) ||  X <- List0], Args0};
-		               {inherited, List0, Arg0} ->
-		                   io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, inherited]),
-			               {List0, Arg0}
-		           end,    
-		           io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE,  {List, Args}]),
-    Args2 = lists:reverse([{var, 1, Val} || {Val, _} <- Args]),  
-    Cons = list_fold(lists:reverse(List)),                           
-    Ast2 = {function, 1, list_to_atom(FunctionName), length(Args2),
-            [{clause, 1, Args2, [], [Cons]}]},
-    Ac = erlydtl_tools:create_module(Ast2 , ModuleName),    
-    case compile:forms(Ac) of
-        {ok, Module, Bin} ->
-            case erlydtl_tools:reload(Module, Bin) of
-                ok ->
-                    erlydtl_tools:write_beam(Module, Bin, "ebin");
-                _ -> 
-                    {error, "reload failed"}
-            end;            
-        _ ->
-           {error, "compilation failed"}
-    end.
-
-
-list_fold([E]) ->
-    E;      
-list_fold([E1, E2]) ->
-    {cons, 1, E2, E1};           
-list_fold([E1, E2 | Tail]) ->
-    lists:foldl(fun(X, T) -> 
-                    {cons, 1, X, T}
-                end, {cons, 1, E2, E1}, Tail).                       
-
-
-transl(nil, [{extends, _, Name}], Out, Args, RelDir) -> 
-    case parse(filename:join([RelDir, Name])) of
-           {ok, ParentAst} ->
-			   [H|T]=ParentAst,
-			   {_, List, Args1} = transl(H, T, [], [], RelDir),
-		       {inherited, [replace_block(X, Out) ||  X <- List], Args1};
-	       {error, Msg} ->
-	           io:format("TRACE ~p:~p ~p~n",[?MODULE, ?LINE, Msg]),
-	           io:format("TRACE ~p:~p Parent Parser failure: ~p~n",[?MODULE, ?LINE, Name]),
-		       {regular, Out, Args}			
-    end;
-	
-transl(nil, [{var, L, Val}], Out, Args, _) ->
-    case lists:keysearch(Val, 2, Args) of
-        false ->
-            Key = list_to_atom(lists:concat(["A", length(Args) + 1])),
-            {regular, [{var, L, Key} | Out], [{Key, Val} | Args]}; 
-        {value, {Key, _}} ->   
-            {regular, [{var, L, Key} | Out], Args}
-    end;
-
-transl(nil, [Token], Out, Args, _) ->
-    {regular, [Token | Out], Args}; 
-	
-transl([H | T], [{var, L, Val}], Out, Args, DocRoot) ->
-    case lists:keysearch(Val, 2, Args) of
-        false ->
-            Key = list_to_atom(lists:concat(["A", length(Args) + 1])),
-            transl(H, T, [{var, L, Key} | Out], [{Key, Val} | Args], DocRoot);
-        {value, {Key, _}} ->  
-            transl(H, T, [{var, L, Key} | Out], Args, DocRoot)
-	end;	 
-	
-transl([H | T], [Token], Out, Args, DocRoot) ->       
-    transl(H, T, [Token | Out], Args, DocRoot).
-
-
-replace_block({block, Name, [nil, Str1]}, List) ->
-	case lists:keysearch(Name, 2, List) of
-		false -> 
-			Str1;
-		{value, {_, _, [nil, Str2]}} ->  
-			Str2
- 	end;
-replace_block(Other, _) ->	
-	Other.
-
-	
-inplace_block({block, _, [nil, Str]}) ->
-	Str;
-inplace_block(Other) ->	
-	Other.
-	
-	
-