Cascading EEx calls..

201 views
Skip to first unread message

mraptor

unread,
Sep 26, 2014, 3:16:14 PM9/26/14
to elixir-l...@googlegroups.com
EEx: If i have a template within a template ... calls in every new template I have to add at the beginning :

<%import MyModule %>

Is it possible to do it just in the root template and propagate it to the children somehow, so that MyModule functions are available everywhere ?
thanks

PS>
Example render() func

def render(view,data) do
   EEx.eval_file(tpl, data: data)
 end

====root.tpl

<%import MyModule %>
<%= render('tpl2.tpl', data) %>

======tpl2.tpl
<%import MyModule %>
<%= render('tpl3.tpl', data) %>

Chris McCord

unread,
Sep 26, 2014, 3:23:26 PM9/26/14
to elixir-l...@googlegroups.com
Take a look at EEx.function_from_file. That way you can precompile the contents within `render` functions and it will allow the nested renders to have the context of the module. It will also make things much faster.

--
You received this message because you are subscribed to the Google Groups "elixir-lang-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-ta...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

mraptor

unread,
Sep 26, 2014, 4:29:29 PM9/26/14
to elixir-l...@googlegroups.com
Here is what I tried to do if I understood you correctly :
1. I created render_root() which is a call to EEx.function_from_file() which would create a function called rendered()
    EEx.function_from_file :def, :rendered, "template.tpl", [:a, :b ]
2. I preserve my render() function i.e. EEx.eval_file()
 

then when I want ot render the whole tree I  just call render_root() (which will generate the rendered() function) and inside the templates I simply call render() whenever I need too.
So to render the whole thing I do :
.render_root() 
.rendered()

Is that what you had in mind.. ? if yes I get when I try to compile :

** (ArgumentError) cannot set attribute @external_resource inside function/macro

José Valim

unread,
Sep 26, 2014, 4:47:32 PM9/26/14
to elixir-l...@googlegroups.com
You need to call function_from_file in the module body for each template. Then you can define the import in the module, before function_from_file and it will be available in each template.

In this scenario, calling each template will be a function call, no evals (which will also be much faster).
--


José Valim
Skype: jv.ptec
Founder and Lead Developer

mraptor

unread,
Sep 26, 2014, 4:56:34 PM9/26/14
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
You mean I have to loop trough all the templates and compile separate function for every template ?

BTW, I don't know them in advance and in what order they have to be compiled, that's why I have this render() function so I can call it whenever I need it ... i.e. the templates may be rendered in different order depending on runtime conditions !
To unsubscribe from this group and stop receiving emails from it, send an email to elixir-lang-talk+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

José Valim

unread,
Sep 27, 2014, 4:42:24 AM9/27/14
to elixir-l...@googlegroups.com
BTW, I don't know them in advance and in what order they have to be compiled, that's why I have this render() function so I can call it whenever I need it ... i.e. the templates may be rendered in different order depending on runtime conditions !

The order doesn't matter, as the order you define functions in an Elixir module doesn't matter when they are called.

So as long as the amount of templates are known at some moment, you can compile them into a module. But if templates can literally be added at any time while your application runs, then you need eval and you would need to repeat the imports on each of them (unless you automatically add the import before evaling.

mraptor

unread,
Sep 28, 2014, 1:27:34 AM9/28/14
to elixir-l...@googlegroups.com, jose....@plataformatec.com.br
Why if I do EEx.function_from_file() in module context it works, but If I do it inside a function I get :


** (ArgumentError) cannot set attribute @external_resource inside function/macro

José Valim

unread,
Sep 28, 2014, 2:09:30 AM9/28/14
to elixir-l...@googlegroups.com
Because function_from_file defines a local function, and you can't  define a local function inside another local function. If someone wants to send a pull request for a better message, it would be welcome.
Reply all
Reply to author
Forward
0 new messages