Coding Views

This is your second pass through this process. The first time, you built a “Hello, World”-style feature, one with a controller, view, and template. Now it’s time for the more detailed explanation that you were promised earlier. In many other web frameworks, the terms view and template are often used synonymously. It’s enough for users to know that when a controller finishes a task, a view is somehow rendered.

In Phoenix, the terminology is a little more explicit. A view is a module containing rendering functions that convert data into a format the end user will consume, like HTML or JSON. You can write such functions as you would any other Elixir function. Those rendering functions can also be defined from templates. A template is a function on that module, compiled from a file containing a raw markup language and embedded Elixir code to process substitutions and loops. The separation of the view and template concepts makes it easy to render data any way you want, be it with a raw function, an embedded Elixir engine, or any other template engine.

In short, views are modules responsible for rendering. Templates are web pages or fragments that allow both static markup and native code to build response pages, compiled into a function.

Let’s build a view in lib/rumbl_web/views/user_view.ex:

 defmodule​ RumblWeb.UserView ​do
 use​ RumblWeb, ​:view
 
  alias Rumbl.Accounts
 
 def​ first_name(%Accounts.User{​name:​ name}) ​do
  name
  |> String.split(​"​​ "​)
  |> Enum.at(0)
 end
 end

We added a simple first_name function to parse a user’s first name from that user’s name field. Next, in lib/rumbl_web/templates, we created a user directory and a new index template in lib/rumbl_web/templates/user/index.html.eex:

 <h1>Listing Users</h1>
 
 <table>
 <%=​ for user <- @users ​do​ ​%>
  <tr>
  <td><b>​<%=​ first_name(user) ​%>​</b> (​<%=​ user.id ​%>​)</td>
  <td>​<%=​ link ​"​​View"​, ​to:​ Routes.user_path(@conn, ​:show​, user.id) ​%>​</td>
  </tr>
 <%​ ​end​ ​%>
 </table>

That’s mostly HTML markup, with a little Elixir mixed in. This template language is called EEx, which stands for Embedded Elixir, and is part of the Elixir’s standard library. At runtime, Phoenix will translate this template to a function using this strategy. EEx executes Elixir code that’s within <%= %> tags, injecting the result into the template. EEx evaluates code within <% %> tags without injecting the result, meaning we’ll use them for code with side effects. Since we generally try to keep side effects out of views wherever possible, we’ll use mostly the <%= %> form. You’ve seen template code before, but we’ll walk through it anyway.

The expression for user <- @users walks through the users, rendering each user using the template code inside the do block, and rolling up the result into the template. Remember, we’ve already populated @users within our index action.

Each user is a map. We render the name field, the id field, and a link. That link comes from a helper function.

Chris says:
Chris says:
Why Are Templates So Fast in Phoenix?

After compilation, templates are functions. Since Phoenix builds templates using linked lists rather than string concatenation the way many imperative languages do, one of the traditional bottlenecks of many web frameworks goes away. Phoenix doesn’t have to make huge copies of giant strings.

Since Elixir has only a single copy of the largest and most frequently used strings in your application, the hardware caching features of most CPUs can come into play. The book’s introduction talked about the performance of the routing layer. The performance of the view layer is just as important. For more details, see Elixir RAM and the Template of Doom.[12]

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.12.136.63