Permalink
Browse files

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

  • Loading branch information...
1 parent c5c019e commit afbb1cdeb8e2fd1fe339ab7571d25b2d80e13f21 @rsaccon rsaccon committed Dec 10, 2007
Showing with 40 additions and 225 deletions.
  1. +2 −2 demo/out/test_extend.html
  2. +1 −1 demo/templates/test_extend.html
  3. +4 −4 src/demo/erlydtl_demo.erl
  4. +33 −31 src/erlydtl/erlydtl.erl
  5. +0 −187 src/erlydtl/erlydtl_api.erl
@@ -1,11 +1,11 @@
-blastring
+bar1string
base template
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,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 %}
@@ -63,17 +63,17 @@ 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").
%%====================================================================
%% 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 ->
View
@@ -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,31 +159,31 @@ 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;
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.
View
@@ -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.
-
-
-

0 comments on commit afbb1cd

Please sign in to comment.