EEx.function_from_file for Heex

with EEx.function_from_file I can create a function from an eex-template, call it and get a rendered string back.

How can I do that with ~H?

You want to use a separate .heex.html file:

  • to define a component
  • use it instead of ~H in a component?

I have not come across an out of box api in phoenix_live_view to achieve the first.
If you are looking for second one - there is no straight forward way to do this.

Couldn’t you just pass HTMLEngine in the options as engine?

1 Like

I want to use ~H as a template engine to create an HTML file (which I can then process with another tool to PDF). I already have these templates working in a liveview-app, but need some of the views as PDF.

I was hoping I’d find an equivalent to EEx — EEx v1.14.0-dev - example:

# sample.html.heex
<MyComponent.greet name={@name} />

# sample.ex
defmodule Sample do
  require HEEx # <--- does not exist
  HEEx.function_from_file(:def, :sample, "sample.html.heex", [:a, :b])
end

# iex
Sample.sample(name: "World")
#=> "Hello, World!"

You mean like

EEx.function_from_file(
  :def, :sample, "sample.eex", [:assigns], engine: Phoenix.LiveView.HTMLEngine)

this returns a %Phoenix.LiveView.Rendered and it doesn’t look like I’ll get a HTML from that easily.

You can pipe the %Phoenix.LiveView.Rendered into
Phoenix.HTML.Safe.to_iodata() |> to_string()
which would return the html resulting string.

4 Likes

indeed. Some times things are so obvious :melting_face:

defmodule Sample do
  require EEx

  EEx.function_from_file(
    :def, :sample, "sample.html.heex", [:assigns], engine: Phoenix.LiveView.HTMLEngine)
end

defmodule MyComponent do
  use Phoenix.Component

  def greet(assigns) do
    ~H"""
    <p>Hello, <%= assigns.name %></p>
    """
  end
end

# sample.html.heex
<MyComponent.greet name={@name} />
iex(1)> Sample.sample(%{name: "World"}) |> Phoenix.HTML.Safe.to_iodata() |> to_string()
"<p>Hello, World</p>"
6 Likes

this (obviously) needs liveview in deps!

Which is enough though, no other deps needed (Jason if you want LV to stop complaining)

 defp deps do
    [
      {:jason, "~> 1.3.0"}, # recommended by LV
      {:phoenix_live_view, "~> 0.17.10"}
    ]
  end

writing to a file does not need to_string

Sample.sample(%{name: "World"})
|> Phoenix.HTML.Safe.to_iodata()
|> then(fn data -> File.write!(path, data) end)
1 Like