erlydtl_demo.erl 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. %%%-------------------------------------------------------------------
  2. %%% File: erlydtl_demo.erl
  3. %%% @author Roberto Saccon <rsaccon@gmail.com> [http://rsaccon.com]
  4. %%% @author Evan Miller <emmiller@gmail.com>
  5. %%% @copyright 2008 Roberto Saccon, Evan Miller
  6. %%% @doc
  7. %%% Demo application and tests
  8. %%% @end
  9. %%%
  10. %%% The MIT License
  11. %%%
  12. %%% Copyright (c) 2007 Roberto Saccon, Evan Miller
  13. %%%
  14. %%% Permission is hereby granted, free of charge, to any person obtaining a copy
  15. %%% of this software and associated documentation files (the "Software"), to deal
  16. %%% in the Software without restriction, including without limitation the rights
  17. %%% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  18. %%% copies of the Software, and to permit persons to whom the Software is
  19. %%% furnished to do so, subject to the following conditions:
  20. %%%
  21. %%% The above copyright notice and this permission notice shall be included in
  22. %%% all copies or substantial portions of the Software.
  23. %%%
  24. %%% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  25. %%% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  26. %%% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  27. %%% AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  28. %%% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  29. %%% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  30. %%% THE SOFTWARE.
  31. %%%
  32. %%% @since 2007-11-17 by Roberto Saccon, Evan Miller
  33. %%%-------------------------------------------------------------------
  34. -module(erlydtl_demo).
  35. -author('rsaccon@gmail.com').
  36. -author('emmiller@gmail.com').
  37. %% API
  38. -export([create_parser/0,
  39. compile_all/0,
  40. compile/1,
  41. compile/3,
  42. render_all/0,
  43. render/1,
  44. render/2]).
  45. %%====================================================================
  46. %% API
  47. %%====================================================================
  48. %%--------------------------------------------------------------------
  49. %% @spec () -> ok | {error, Reason::string()}
  50. %% @doc creates the parser source code and compiles it
  51. %% @end
  52. %%--------------------------------------------------------------------
  53. create_parser() ->
  54. case erlydtl:create_parser() of
  55. ok ->
  56. io:format("parser creation success ~n");
  57. {error, Reason} ->
  58. io:format("parser creation failure: ~p~n",[Reason])
  59. end.
  60. %%--------------------------------------------------------------------
  61. %% @spec () -> any()
  62. %% @doc compiles all templates to beam files
  63. %% @end
  64. %%--------------------------------------------------------------------
  65. compile_all() ->
  66. compile("autoescape"),
  67. compile("comment"),
  68. compile("extends"),
  69. compile("filters"),
  70. compile("for"),
  71. compile("for_preset"),
  72. compile("for_list"),
  73. compile("for_list_preset"),
  74. compile("for_records"),
  75. compile("for_records_preset"),
  76. compile("for_tuple"),
  77. compile("if"),
  78. compile("if_preset"),
  79. compile("ifequal"),
  80. compile("ifequal_preset"),
  81. compile("ifnotequal"),
  82. compile("ifnotequal_preset"),
  83. compile("include"),
  84. compile("var"),
  85. compile("var_preset"),
  86. compile("var_error"),
  87. compile("custom_tag"),
  88. compile("custom_tag_error"),
  89. compile("custom_call").
  90. %%--------------------------------------------------------------------
  91. %% @spec (string()) -> any()
  92. %% @doc
  93. %% compiles the template to beam files
  94. %% @end
  95. %%--------------------------------------------------------------------
  96. compile("var" = Name) ->
  97. compile(Name, ".html", []);
  98. compile("var_preset" = Name) ->
  99. Vars = [{preset_var1, "preset-var1"}, {preset_var2, "preset-var2"}],
  100. compile(Name, ".html", Vars);
  101. compile("var_error" = Name) ->
  102. compile(Name, ".html", []);
  103. compile("extends" = Name) ->
  104. compile(Name, ".html", []);
  105. compile("include" = Name) ->
  106. compile(Name, ".html", []);
  107. compile("autoescape" = Name) ->
  108. compile(Name, ".html", []);
  109. compile("if" = Name) ->
  110. compile(Name, ".html", []);
  111. compile("if_preset" = Name) ->
  112. Vars = [{var1, "something"}],
  113. compile(Name, ".html", Vars);
  114. compile("ifequal" = Name) ->
  115. compile(Name, ".html", []);
  116. compile("ifequal_preset" = Name) ->
  117. Vars = [{var1, "foo"}, {var2, "foo"}],
  118. compile(Name, ".html", Vars);
  119. compile("ifnotequal" = Name) ->
  120. compile(Name, ".html", []);
  121. compile("ifnotequal_preset" = Name) ->
  122. Vars = [{var1, "foo"}, {var2, "foo"}],
  123. compile(Name, ".html", Vars);
  124. compile("filters" = Name) ->
  125. compile(Name, ".html", []);
  126. compile("comment" = Name) ->
  127. compile(Name, ".html", []);
  128. compile("for" = Name) ->
  129. compile(Name, ".html", []);
  130. compile("for_records" = Name) ->
  131. compile(Name, ".html", []);
  132. compile("for_list" = Name) ->
  133. compile(Name, ".html", []);
  134. compile("for_tuple" = Name) ->
  135. compile(Name, ".html", []);
  136. compile("for_list_preset" = Name) ->
  137. Vars = [{fruit_list, [["apple", "apples"], ["banana", "bananas"], ["coconut", "coconuts"]]}],
  138. compile(Name, ".html", Vars);
  139. compile("for_preset" = Name) ->
  140. Vars = [{fruit_list, ["preset-apple", "preset-banana", "preset-coconut"]}],
  141. compile(Name, ".html", Vars);
  142. compile("for_records_preset" = Name) ->
  143. Link1 = [{name, "Amazon (preset)"}, {url, "http://amazon.com"}],
  144. Link2 = [{name, "Google (preset)"}, {url, "http://google.com"}],
  145. Link3 = [{name, "Microsoft (preset)"}, {url, "http://microsoft.com"}],
  146. Var = [{software_links, [Link1, Link2, Link3]}],
  147. compile(Name, ".html", Var);
  148. compile("custom_tag" = Name) ->
  149. compile(Name, ".html", []);
  150. compile("custom_tag_error" = Name) ->
  151. compile(Name, ".html", []);
  152. compile("custom_call" = Name) ->
  153. compile(Name, ".html", []);
  154. compile(Name) ->
  155. io:format("No such template: ~p~n",[Name]).
  156. %%--------------------------------------------------------------------
  157. %% @spec (string(), string()) -> any()
  158. %% @doc
  159. %% compiles the template to beam files
  160. %% @end
  161. %%--------------------------------------------------------------------
  162. compile(Name, Ext, Vars) ->
  163. DocRoot = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "templates"]),
  164. Module = "test_" ++ Name,
  165. File = filename:join([DocRoot, Module ++ Ext]),
  166. case erlydtl_compiler:compile(File, Module, DocRoot, Vars) of
  167. ok ->
  168. io:format("compile success: ~p~n",[Module]);
  169. {error, Reason} ->
  170. case string:str(File, "error") of
  171. 0 ->
  172. io:format("compile failure: ~p ~p~n", [Module, Reason]);
  173. _ ->
  174. Explanation = "==>> this is ok, we are testing an error !",
  175. io:format("compile failure: ~p ~p ~s~n",[Module, Reason, Explanation])
  176. end
  177. end.
  178. %%--------------------------------------------------------------------
  179. %% @spec () -> any()
  180. %% @doc renders template to a file
  181. %% @end
  182. %%--------------------------------------------------------------------
  183. render_all() ->
  184. render("autoescape"),
  185. render("comment"),
  186. render("extends"),
  187. render("filters"),
  188. render("for"),
  189. render("for_preset"),
  190. render("for_list"),
  191. render("for_tuple"),
  192. render("for_list_preset"),
  193. render("for_records"),
  194. render("for_records_preset"),
  195. render("if"),
  196. render("if_preset"),
  197. render("ifequal"),
  198. render("ifequal_preset"),
  199. render("ifnotequal"),
  200. render("ifnotequal_preset"),
  201. render("include"),
  202. render("var"),
  203. render("var_preset"),
  204. render("var_error"),
  205. render("custom_tag"),
  206. render("custom_call").
  207. %%--------------------------------------------------------------------
  208. %% @spec (string()) -> ok()
  209. %% @doc renders template to a file
  210. %% @end
  211. %%--------------------------------------------------------------------
  212. render("autoescape" = Name) ->
  213. render(Name, [{var1, "<b>bold</b>"}]);
  214. render("comment" = Name) ->
  215. render(Name, []);
  216. render("extends" = Name) ->
  217. render(Name, [{base_var, "base-barstring"}, {test_var, "test-barstring"}]);
  218. render("filters" = Name) ->
  219. render(Name, [{'list', ["eins", "zwei", "drei"]}]);
  220. render("include" = Name) ->
  221. render(Name, [{var1, "foostring1"}, {var2, "foostring2"}]);
  222. render("if" = Name) ->
  223. render(Name, [{var1, "something"}]);
  224. render("if_preset" = Name) ->
  225. render(Name, []);
  226. render("ifequal" = Name) ->
  227. render(Name, [{var1, "foo"}, {var2, "foo"}, {var3, "bar"}]);
  228. render("ifequal_preset" = Name) ->
  229. render(Name, [{var3, "bar"}]);
  230. render("ifnotequal" = Name) ->
  231. render(Name, [{var1, "foo"}, {var2, "foo"}, {var3, "bar"}]);
  232. render("ifnotequal_preset" = Name) ->
  233. render(Name, [{var3, "bar"}]);
  234. render("for" = Name) ->
  235. render(Name, [{fruit_list, ["apple", "banana", "coconut"]}]);
  236. render("for_preset" = Name) ->
  237. render(Name, []);
  238. render("for_list" = Name) ->
  239. %render(Name, [{fruit_list, [["apple", "apples"], ["banana", "bananas"], ["coconut", "coconuts"]]}]);
  240. render(Name, [{fruit_list, [["apple", "apples", "$1"], ["banana", "bananas", "$2"], ["coconut", "coconuts", "$500"]]}]);
  241. render("for_tuple" = Name) ->
  242. %render(Name, [{fruit_list, [{"apple", "apples", "$1"}, {"banana", "bananas", "$2"}, {"coconut", "coconuts", "$500"}]}]);
  243. render(Name, [{fruit_list, [{"apple", "apples"}, {"banana", "bananas"}, {"coconut", "coconuts"}]}]);
  244. render("for_list_preset" = Name) ->
  245. render(Name, []);
  246. render("for_records" = Name) ->
  247. Link1 = [{name, "Amazon"}, {url, "http://amazon.com"}],
  248. Link2 = [{name, "Google"}, {url, "http://google.com"}],
  249. Link3 = [{name, "Microsoft"}, {url, "http://microsoft.com"}],
  250. render(Name, [{link_list, [Link1, Link2, Link3]}]);
  251. render("for_records_preset" = Name) ->
  252. Link1 = [{name, "Canon"}, {url, "http://canon.com"}],
  253. Link2 = [{name, "Leica"}, {url, "http://leica.com"}],
  254. Link3 = [{name, "Nikon"}, {url, "http://nikon.com"}],
  255. render(Name, [{photo_links, [Link1, Link2, Link3]}]);
  256. render("var" = Name) ->
  257. render(Name, [{var1, "foostring1"}, {var2, "foostring2"}, {var_not_used, "foostring3"}]);
  258. render("var_preset" = Name) ->
  259. render(Name, [{var1, "foostring1"}, {var2, "foostring2"}]);
  260. render("var_error" = Name) ->
  261. render(Name, [{var1, "foostring1"}]);
  262. render("custom_tag" = Name) ->
  263. render(Name, []);
  264. render("custom_call" = Name) ->
  265. render(Name, []);
  266. render(Name) ->
  267. io:format("No such template: ~p~n",[Name]).
  268. %%--------------------------------------------------------------------
  269. %% @spec (atom(), string(), string()) -> any()
  270. %% @doc renders template to a file
  271. %% @end
  272. %%--------------------------------------------------------------------
  273. render(Name, Args) ->
  274. OutDir = filename:join([filename:dirname(code:which(?MODULE)),"..", "demo", "out"]),
  275. Module = list_to_atom("test_" ++ Name),
  276. case catch Module:render(Args) of
  277. {ok, Val} ->
  278. case file:open(filename:join([OutDir, filename:basename(Module:source())]), [write]) of
  279. {ok, IoDev} ->
  280. file:write(IoDev, Val),
  281. file:close(IoDev),
  282. io:format("render success: ~p~n",[Module]);
  283. _ ->
  284. io:format("file writing failure: ~p~n",[Module])
  285. end;
  286. {error, Reason} ->
  287. case string:str(Name, "error") of
  288. 0 ->
  289. io:format("render failure: ~p ~p~n",[Module, Reason]);
  290. _ ->
  291. Explanation = "==>> this is ok, we are testing an error !",
  292. io:format("render failure: ~p ~p ~s~n",[Module, Reason, Explanation])
  293. end
  294. end.
  295. %%====================================================================
  296. %% Internal functions
  297. %%====================================================================