I am trying to cache static web pages in ETS, and using render_to_iodata does not seem to include the layout. I was wondering the proper way to do this. Here is how I am currently using it in my controller:
def post(conn, _param) do
rendered_page = Phoenix.View.render_to_iodata(BlogWeb.LayoutView, "app.html",
%{
conn: conn,
view_module: BlogWeb.PostView,
view_template: "post.html"
})
html(conn, rendered_page)
end
What happens is that this spins forever and nothing gets loaded, and nothing is really logged to the console.
Since you’re not getting any errors it’s hard to say what’s wrong. I’ve never tried to do it that way, but I can suggest an alternative solution. You can cache rendered content by using Plug.Conn.register_before_send/2. Here’s some untested code
def post(conn, _param) do
conn
|> Plug.Conn.register_before_send(cache/1)
|> render("post.html")
end
def cache(conn) do
content = :erlang.iolist_to_binary(conn.resp_body)
:ets.insert(:table, {you_pick_your_key, content})
conn
end
The reason you want to coerce the iodata to binary is that based on experience the ETS memory usage will balloon if you don’t.