Imagine you have a core component for LiveView/Phoenix component, and it has some static component like icon
For example:
<Heroicons.inbox_stack class="w-6 h-6 mx-auto stroke-current" />
You want to load it in a loop something like this:
<.block :for={{id, title, icon_module} <- tailwind_settings} id={id} title={title}>
<icon_module class="w-6 h-6 mx-auto stroke-current" />
</.block>
How can we implement it?
Thank you in advance.
I found Phoenix.LiveView.HTMLEngine.component
, but I could not use with string name of Elixir module and function like: "Elixir.Heroicons.inbox_stack"
<.block :for={{id, title, module} <- tailwind_settings} id={id} title={title}>
<%= Phoenix.LiveView.HTMLEngine.component(
String.to_existing_atom(module),
[class: "w-6 h-6 mx-auto stroke-current"],
{__ENV__.module, __ENV__.function, __ENV__.file, __ENV__.line}
) %>
</.block>
This function needs 3 arity
and I can’t use apply
, so String.to_existing_atom(module)
is just used for converting to module
Do you have any idea?
Thanks
I did like this, finally see it works:
<.block :for={{id, title, module} <- tailwind_settings} id={id} title={title}>
<%= Phoenix.LiveView.HTMLEngine.component(
Code.eval_string("&#{module}/1") |> elem(0),
[class: "w-6 h-6 mx-auto stroke-current"],
{__ENV__.module, __ENV__.function, __ENV__.file, __ENV__.line}
) %>
</.block>
If you have another way, please let me know
Thanks
Function.capture/3
is what you’re looking for.
1 Like
LostKobrakai:
Function.capture
I tried this, I have full name of module and its function which is like this: "Heroicons.inbox_stack"
, but it needs to have module and function name separately.
I’d suggest changing the input then to e.g. provide the function name only. Or the module and function name separately.
1 Like
Yes, you’re right, I just have one question,
<.block :for={{id, title, module} <- tailwind_settings} id={id} title={title}>
<%= Phoenix.LiveView.HTMLEngine.component(
Code.eval_string("&#{module}/1") |> elem(0),
[class: "w-6 h-6 mx-auto stroke-current"],
{__ENV__.module, __ENV__.function, __ENV__.file, __ENV__.line}
) %>
</.block>
This code is working now, I have no problem. The module
is hard-coded, and I do not get it from user input, with these situations I am going to face with security issue?
Hey all! It seems that HTMLEngine.component
is no longer there… does anyone have another way of dynamically render a component?
You rock @LostKobrakai ! Thanks a lot! I need to find a “public” api to do this before it changes again.