Phoenix function component wrapper that uses dynamic template function

Hi!

I’m trying to build a phoenix live component which wraps around other components, and I have a question about using the function component LiveView helper found in Phoenix.LiveView.Helpers

My wrapper component (I’ll call it MyAppWeb.Parent) is supposed to take in, via render assigns, the module name and template function name for the component it wraps (call these @body_component_module and @body_component_template). I also want to be able to use the inner_block slot to add some markup to every body component. Can the more-common component helper syntax of

~H"""
<[module_name].[template_function_name] assign1="foo" assign2="bar">
   <div> 
     My inner_block content
   </div>
</[module_name].[template_function_name]>

be used in my case where [module_name] and [template_function_module] can be dynamically passed in as the assigns @body_component_module and @body_component_template?

I was able to get an alternative approach partially working by using the <%= component() %> syntax:

~H"""
<%= component(
  Function.capture(@body_component_module, @body_component_template, 1), 
  assign1: "foo", 
  assign2: "bar") %>
"""

But I can’t quite figure out how to pass it the inner_block markup so that the body component template can render_slot(@inner_block)

Can someone suggest how to either use the
<[module_name].[template_function_name] /> syntax with dynamic values, or how to pass an inner block to <%= component() %>?

Thank you!

1 Like

FYI: In phoenix 0.18 it became a bit tricker as Phoenix.LiveView.Helpers.component/2 moved to Phoenix.LiveView.HTMLEngine.component/3 and now asks caller data to be passed. source

Today with LiveView 0.18.18 i got this working with

<%= Phoenix.LiveView.TagEngine.component(
          Function.capture(@target_module, @target_function, 1),
          [assign1: 1, assign2: 2],
          {__ENV__.module, __ENV__.function, __ENV__.file, __ENV__.line}
        ) %>

docs: Phoenix.LiveView.TagEngine.html#component/3

2 Likes