Viewing to-do list
Creating a new route
Similar to how we have created the GET /api/todo
endpoint, we will first create the route in router.ex
. This time, add it to the existing scope "/"
that was given.
Creating the associated controller action
Once done, we need to add the associated controller action todo
in the PageController
. We will disable the default layout as we want to style the web page ourselves.
Notice that we directly retrieve the information needed for rendering to the to-do list and pass it as a keyword to the render/3
function. This way, we are able to use this information directly in the page.
Introducing HEEx (HTML + EEx)
Finally, add a file to lib/practical_elixir_demo_web/controllers/page_html/
titled todo.html.heex
. Note that the filename must correspond to the atom specified in the render/2
function call, i.e. todo
.
Now that we have the todo.html.heex
file, we can design the to-do list view of our application.
Then, you can populate the file with the following:
Nothing too fancy, but as you can see, the dummy to-do list we have constructed earlier now appears on the page.
With this, we can introduce several other concepts in Phoenix and HEEx.
Evaluating expressions
You may have noticed the unique <%= %>
syntax used in the code above. What it effectively does is executes the expression within the block and inserts the results into the page. You can try it out by adding a line like <p><%= 5 + 5 %></p>
and it will render to the front-end as 10
.
You may also use <% %>
(without =
) if your expression does not return any values or you do not wish to output the return value. As such, we can replace <%= else %>
with <% else %>
too!
Reading values from controller
Notice that previously, we had passed a todo_list
keyword into the render/3
function in the page_controller.ex
file. We have accessed this variable from the view via the @todo_list
syntax.
This is a nifty way to access variables passed to the view via the controller.
Functional components
Functional components serve as a shared abstraction for commonly used UI that can be reused across views and layouts. They are not a new concept, and can often be seen in other front-end libraries like React.
For our demo, let's abstract each to-do list item to its own functional component so that any modifications made to one will be uniform across all.
To declare a new functional component for that view controller, all you need to do is to add a function with the function name as the name of the intended functional component and it must receive an argument called assigns
. The purpose of this argument is to allow the HEEx to pass data to the functional component to be used within the functional component:
You use the @<variable>
notation to access values passed to the functional component via assigns
. Also notice that we have effectively moved the entire block found in the for
loop into the functional component.
Then, you can use the functional component in the HEEx as follows:
We have replaced the bulk of the for
loop body with the functional component which is referenced via the .<functional_component>
notation with the @item
given as an a HTML attribute. Phoenix intelligently does the mapping from HEEx to functional component.
Styling with Phoenix
The current to-do list view is quite plain. Let's spruce things up a bit.
As mentioned in Directory structure, all CSS files are stored under assets/
. However, if you opened the assets/css/app.css
file, you will notice that there are the following three lines:
So let's get to styling our web application. We will not cover how CSS styling with Tailwind works because that's out of the scope of this guide.
These styles should result in the following page:
Now that the to-do list is more visually appealing, let's dive into setting up dynamic behavior.
Last updated