skovmand
Easiest way to render a .heex template to an HTML string?
Usually in tests of my views, I have used safe_to_string() to convert a returned :safe tuple to HTML that I can assert on. For example:
test "greets the user" do
user = %{name: "Kurt"}
html = MyView.render("some_template.html", user: user) |> Phoenix.HTML.safe_to_string()
assert html =~ "Hello, Kurt"
end
However, if the template is a .heex file, this no longer works because the return struct is a %Phoenix.LiveView.Rendered{} struct, e.g.:
%Phoenix.LiveView.Rendered{
dynamic: #Function<0.64041902/1 in PeanutButterWeb.PageView."hello.html"/1>,
fingerprint: 29760870404026531075951007545402085092,
root: true,
static: ["<p>Hello, Kurt</p>"]
}
This is also true, even if I’m rendering from a plain view.
Is there a simple way to convert this struct to plain html?
Thanks ![]()
Marked As Solved
skovmand
Okay, here’s what I found after digging around for a while:
test "greets the user" do
user = %{name: "Kurt"}
html = MyView.render("some_template.html", user: user)
|> Phoenix.HTML.Safe.to_iodata()
|> IO.iodata_to_binary()
assert html =~ "Hello, Kurt"
end
Will give the returned HTML as string, ready for assertions.
By the way, there are very good docs available about it here: Phoenix.LiveView.Engine — Phoenix LiveView v1.2.5
Also Liked
petrus-jvrensburg
Just to add: this also works for rendering components to plain HTML, without having to define a separate template / view, for example:
DevApp.ProductComponent.render(%{product: %{id: 1}})
|> Phoenix.HTML.Safe.to_iodata()
|> IO.iodata_to_binary()
sreyansjain
You can try
Phoenix.Template.render_to_string(<module_name>, function name in string, "html", assigns)
for example
Phoenix.Template.render_to_string(MyAppWeb.TaskHTML, "show_task", "html", task: task)
rhcarvalho
Nice finding, thanks for sharing!
I found one more usable API that achieves the same, with the advantage of a compilation error in case the template name/function is invalid:
MyModule.my_function_component(%{some: assign_value})
|> Phoenix.LiveViewTest.rendered_to_string()
Phoenix.LiveViewTest.rendered_to_string/1’s implementation is, no surprise, similar to the first solution in this thread:
def rendered_to_string(rendered) do
rendered
|> Phoenix.HTML.html_escape()
|> Phoenix.HTML.safe_to_string()
end
Example usage
Passing some HTML code to my template, for example an embed code that the user can copy:
def mount(%{"id" => id}, _session, socket) do
socket =
socket
|> assign(
id: id,
embed_code: embed_code(%{id: id}) |> Phoenix.LiveViewTest.rendered_to_string()
# embed_code: Phoenix.Template.render_to_string(__MODULE__, "embed_code", "html", %{id: id})
)
{:ok, socket}
end
attr :id, :string, required: true
def embed_code(assigns) do
~H"""
...<%= @id %>...
"""
end
Last Post!
rhcarvalho
I could not figure out how to skip the annotations when they are globally enabled in dev. Would you have an example of how to skip them?
Having the annotations in dev is not problem since they won’t be there in prod, but your comment got me curious ![]()
In my testing everything rendered off a ~H"""...""" HEEx template in an environment with annotations enabled gets the annotations. IIUC that’s expected because sigil_H/2 is a macro that injects the annotations at compilation time.
It’s the first time I’m looking at this code, so excuse me if I make unsound conclusions.
My reading is that sigil_H/1 calls EEx.compile_string/2 passing Phoenix.LiveView.HTMLEngine. The former will do the annotations based on Application.get_env(:phoenix_live_view, :debug_heex_annotations, false).
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #elixirconf-us
- #advent-of-code
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #hex









