How to embed external html file inside of LiveView render

I am using Phoenix Swoosh to generate emails for my app, but I want to show the user what the automated email will look like.

My LiveView render function looks like this:

defp render_welcome_template(assigns) do
    email_data =
      %{email_header: "Moderator has Approved your Request!",
        to_username: "MEMBER_USERNAME",
        group_name: assigns.group_name,
        from_username: assigns.moderator.username,
        reply_link: GroupMail.build_reply_link(assigns.moderator.id, assigns.group_id),
        group_link: GroupMail.build_group_link(assigns.group_id)
      }
   Map.put(assigns, :email_data, email_data)
    ~H"""
      <h2>Edit Welcome Template</h2>
      <div>Below is the email message that will be sent when the moderator approves a new member. </div>

      ***** THIS IS WHERE I WANT TO EMBED THAT HTML BUT THE FOLLOWING DOESNT WORK:
        <%= render "myapp_web/templates/group_mail/approved_group_member.html", @email_data %>
    """
  end

I was using advice from @LostKobrakai and @Kurisu from this post, but I think that render function only works in a standard Phoenix app where you have access to Conn. I only have access to Socket.

The error I get is: undefined function render/2

How can I pull in the html being used for Swoosh and render it with assigns just for display?

Worst case, I can just copy the html into my LiveView, but that creates a support headache. I risk modifying the HTML file and not updating the liveivew version. Hoping there is a way to embed that HTML into my Liveview render.

1 Like

You can use Phoenix.View.render/3 directly for this:

<%= Phoenix.View.render MyAppWeb.GroupMailView, "approved_group_member.html", @email_data %>

You would need to define a MyAppWeb.GroupMailView module that does use MyAppWeb, :view,

2 Likes

Thanks

Ahhhh … I was looking at Phoenix.Controller.render. I didn’t realize there was also a render in Phoenix.View! For anyone else who runs into this issue:

First see solution given by @trisolaran. That fixed the problem.

In reading up more about Phoenix.view.render, I ran across this page on Sharing Views and Templates. I completely missed this because I was looking at Phoenix.Controller.render hexdocs.

Thank you @trisolaran for the solution!

1 Like

In current docs this (Phoenix.View) is not even listed. Do we have a proper way of rendering pure HTML partials w/o Phoenix.View?

What do you consider a pure html partial? Function component results can be turned into html without Phoenix.View using Phoenix.HTML.Safe — Phoenix.HTML v3.3.3.

1 Like

A static, HTML only file, generated by an external toolchain

Importing external files has always been (Phoenix.View wraps it) and still is (Phoenix.Component wraps it) the responsibility of Phoenix.Template. Though as the name states it’s meant to import template files more than static files, but you could have a template engine, which just wraps the static content in a function – or you’re just fine with the html being parsed for template parts only for none to be found.

1 Like

Roger. In the case at hand, the files in question are not large so trying to parse them “for no reason” wouldn’t hurt much but in general case I’d rather prefer not to

A simple noop engine shouldn’t be hard to implement. Though this cost is at compile time as well, so unless you’re importing loads of files you might not even notice.