I'm trying to understand the difference between the different render
functions in Phoenix. Specifically, I notice there are several different render
functions in a Phoenix View and a Phoenix Template.
For example, within a Phoenix Controller, it's common to see something like this:
# assume this is UserController
def index(conn, _params) do
users = Repo.all(Users) # let's assume that this gives you all your users
render conn, "index.html", users: users
end
Within the index.html
template associated with this View (i.e. UserView), you can see something like this:
# index.html
<ul>
<%= for user <- @users do %>
<li><%= render "user.html", user: user %></li>
<% end %>
</ul>
# user.html
<p><%= @user.name %></p>
My understanding is that the render
function inside of the index.html
template is compiled to a render
function inside of the UserView
. Also, after digging around in iex
, it seems like the render
function in the UserController
's index action comes from Phoenix.Controller.render/3
.
However, I notice that inside of the default app.html.eex
template file, there's a render function that looks like this:
<%= render @view_module, @view_template, assign %>
This doesn't seem to match the signatures of the previous render functions. Can anyone help explain where this render is coming from and how it works?
Phoenix.View
has a descriptive documentation, and if still in doubt, there is a source code for Phoenix.View.render/3
and Phoenix.Controller.render/{1,3,4}
on hand.
The related quote from the documentation:
This inner representation allows us to render and compose templates easily. For example, if you want to render JSON data, we could do so by adding a “show.json” entry to render/2 in our view:
defmodule YourApp.UserView do use YourApp.View def render("show.json", %{user: user}) do %{name: user.name, address: user.address} end end
The Phoenix.Controller.render/4
is passed the conn struct which picks up a number of things like overriding the layout, the view, plash messages, assigns, etc. So, you will see render called that way in controllers.
The render "templ.html", opts
version renders the template of the same View of the caller. This can be used from a template to render a partial.
The Phoenix.View.render App.MyView, "templ.html", opts
is used to render a template from a different view. That is why its called that way from the layout template.
They all end up calling the App.MyView.render/2
. If you have templates then those functions will exist. But you can create your own render function in the view and call it as was pointed out in the answer with the json example.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With