Skip to content

Commit c8c6cea

Browse files
committed
Streamline entry points to Phoenix.LiveView docs
1 parent 145f718 commit c8c6cea

File tree

5 files changed

+44
-48
lines changed

5 files changed

+44
-48
lines changed

guides/components.md

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,20 @@
44
55
> **Requirement**: This guide expects that you have gone through the [request life-cycle guide](request_lifecycle.html).
66
7-
The Phoenix endpoint pipeline takes a request, routes it to a controller, and calls a view module to render a template. The view interface from the controller is simple – the controller calls a view function with the connections assigns, and the function's job is to return a HEEx template. We call any function that accepts an `assigns` parameter and returns a HEEx template a *function component*. Function components are defined with the help of the [`Phoenix.Component`](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html) module.
7+
The Phoenix endpoint pipeline takes a request, routes it to a controller, and calls a view module to render a template. The view interface from the controller is simple – the controller calls a view function with the connections assigns, and the function's job is to return a HEEx template. We call any function that accepts an `assigns` parameter and returns a HEEx template a *function component*.
88

9-
Function components are the essential building block for any kind of markup-based template rendering you'll perform in Phoenix. They serve as a shared abstraction for the standard MVC controller-based applications, LiveView applications, layouts, and smaller UI definitions you'll use throughout other templates.
9+
> The Phoenix framework is designed for HTML applications, JSON APIs, GraphQL endpoints, etc. For this reason, all of the functionality related to HTML rendering comes as part of two separate packages:
10+
>
11+
> * [`phoenix_html`](https://hexdocs.pm/phoenix_html) - defines the building blocks for writing HTML safely. In your project, you'll interact primarily with the `Phoenix.HTML` module, which is imported by default in all templates
12+
>
13+
> * [`phoenix_live_view`](https://hexdocs.pm/phoenix_live_view) - a library for rich, real-time user experiences with server-rendered HTML. While LiveView provides several abstraction for building collaborative and dynamic applications, it also defines the `HEEx` template language, function components, and JS commands, which brings powerful abstractions for all kinds of server-rendered HTML applications
1014
11-
In this chapter, we will recap how components were used in previous chapters and find new use cases for them.
15+
In this chapter, we will recap how components are used and dig deeper to discover new use cases.
1216

1317
## Function components
1418

19+
Function components are the essential building block for any kind of markup-based template rendering you'll perform in Phoenix. They serve as a shared abstraction for the standard MVC controller-based applications, LiveView applications, layouts, and smaller UI definitions you'll use throughout other templates. Their documentation is available in [the `Phoenix.Component` module](https://hexdocs/phoenix_live_view/Phoenix.Component.html).
20+
1521
At the end of the Request life-cycle chapter, we created a template at `lib/hello_web/controllers/hello_html/show.html.heex`, let's open it up:
1622

1723
```heex
@@ -31,7 +37,7 @@ At the end of the Request life-cycle chapter, we created a template at `lib/hell
3137
...
3238
```
3339

34-
A function component is just a function that receives a map of `assigns` as argument and renders part of a template using the `~H` sigil. Let's try defining our own component by hand.
40+
So far, all of the function components we have defined also worked as templates. Let's learn more about them by defining our own component with the intent of encapsulating some HTML markup.
3541

3642
Imagine we want to refactor our `show.html.heex` to move the rendering of `<h2>Hello World, from {@messenger}!</h2>` to its own function. Remember that `show.html.heex` is embedded within the `HelloHTML` module. Let's open it up:
3743

@@ -61,7 +67,7 @@ defmodule HelloWeb.HelloHTML do
6167
end
6268
```
6369
64-
We declared the attributes we accept via the `attr/3` macro provided by `Phoenix.Component`, then we defined our `greet/1` function which returns the HEEx template.
70+
We declared the attributes we accept via the [`Phoenix.Component.attr/3`](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#attr/3) macro, then we defined our `greet/1` function which returns the HEEx template.
6571
6672
Next we need to update `show.html.heex`:
6773
@@ -73,17 +79,21 @@ Next we need to update `show.html.heex`:
7379
</Layouts.app>
7480
```
7581
76-
When we reload `http://localhost:4000/hello/Frank`, we should see the same content as before. Since the `show.html.heex` template is embedded within the `HelloHTML` module, we were able to invoke the function component directly as `<.greet messenger="..." />`. If the component was defined elsewhere, we would need to give its full name: `<HelloWeb.HelloHTML.greet messenger="..." />`.
82+
When we reload `http://localhost:4000/hello/Frank`, we should see the same content as before! The `show.html.heex` is now invoking two different funcion components:
83+
84+
* `<Layouts.app` - the syntax for invoking function componente defined in a separate module and it follows the same rules as calling any other function in Elixir
85+
86+
* `<.greet` - when the function component is defined in the same module as the template, we can skip the module name, and invoke the component using its name prefixed with a dot
7787
78-
By declaring attributes as required, Phoenix will warn at compile time if we call the `<.greet />` component without passing attributes. If an attribute is optional, you can specify the `:default` option with a value:
88+
Since the `show.html.heex` template is embedded within the `HelloHTML` module, we were able to invoke the function component directly as `<.greet messenger="..." />`. If the component was defined elsewhere, we would need to give its full name, such as: `<HelloWeb.HelloHTML.greet messenger="..." />`.
89+
90+
By declaring attributes as required, Phoenix will warn if we call the `<.greet />` component without passing attributes. If an attribute is optional, you can specify the `:default` option with a value:
7991
8092
```
8193
attr :messenger, :string, default: nil
8294
```
8395
84-
Overall, function components are the essential building block of Phoenix rendering stack. The majority of the times, they are functions that receive a single argument called `assigns` and call the `~H` sigil, as we did in `greet/1`. They can also be invoked from templates, with compile-time validation of its attributes declared via `attr`.
85-
86-
Next, let's fully understand the expressive power behind the HEEx template language.
96+
Overall, function components are the essential building block of Phoenix rendering stack. Next, let's fully understand the expressive power behind the HEEx template language.
8797
8898
## HEEx
8999

guides/controllers.md

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -159,8 +159,6 @@ Or you can pass the assigns directly to `render` instead:
159159

160160
Generally speaking, once all assigns are configured, we invoke the view layer. The view layer (`HelloWeb.HelloHTML`) then renders `show.html` alongside the layout and a response is sent back to the browser.
161161

162-
[Components and HEEx templates](components.html) have their own guide, so we won't spend much time on them here. What we will look at is how to render different formats from inside a controller action.
163-
164162
## New rendering formats
165163

166164
Rendering HTML through a template is fine, but what if we need to change the rendering format on the fly? Let's say that sometimes we need HTML, sometimes we need plain text, and sometimes we need JSON. Then what?

guides/request_lifecycle.md

Lines changed: 21 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ defmodule HelloWeb.HelloHTML do
117117
end
118118
```
119119

120-
To add templates to this view, we can define them as function components in the module or in separate files.
120+
To add templates to this view, we can define them as functions in the module or in separate files.
121121

122-
Let's start by defining a function component:
122+
Let's start by defining a function:
123123

124124
```elixir
125125
defmodule HelloWeb.HelloHTML do
@@ -133,11 +133,9 @@ defmodule HelloWeb.HelloHTML do
133133
end
134134
```
135135

136-
We defined a function that receives `assigns` as arguments and used [the `~H` sigil](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) to specify the content we want to render. Inside the `~H` sigil, we used a templating language called HEEx, which stands for "HTML+EEx". `EEx` is a library for embedding Elixir that ships as part of Elixir itself. "HTML+EEx" is a Phoenix extension of EEx that is HTML aware, with support for HTML validation, components, and automatic escaping of values. The latter protects you from security vulnerabilities like Cross-Site Scripting with no extra work on your part.
136+
We defined a function that receives `assigns` as arguments and used [the `~H` sigil](https://hexdocs.pm/phoenix_live_view/Phoenix.Component.html#sigil_H/2) to specify the content we want to render. Inside the `~H` sigil, we used a templating language called HEEx, which stands for "HTML+EEx". `EEx` is a library for embedding Elixir that ships as part of Elixir itself. "HTML+EEx" is a Phoenix extension of EEx that is HTML aware, with support for HTML validation, components, and automatic escaping of values. The latter protects you from security vulnerabilities like Cross-Site Scripting with no extra work on your part. We say that any function that receives `assigns` and returns templates to be a **function component**.
137137

138-
A template file works in the same way. Function components are great for smaller templates and separate files are a good choice when you have a lot of markup or your functions start to feel unmanageable.
139-
140-
Let's give it a try by defining a template in its own file. First, delete our `def index(assigns)` function from above and replace it with an `embed_templates` declaration:
138+
A template file works in the same way. Let's give it a try by defining a template in its own file. First, delete our `def index(assigns)` function from above and replace it with an `embed_templates` declaration:
141139

142140
```elixir
143141
defmodule HelloWeb.HelloHTML do
@@ -147,54 +145,44 @@ defmodule HelloWeb.HelloHTML do
147145
end
148146
```
149147

150-
Here we are telling `Phoenix.Component` to embed all `.heex` templates found in the sibling `hello_html` directory into our module as function definitions.
148+
Here we are saying we want to embed all `.heex` templates found in the sibling `hello_html` directory into our module as function components.
149+
150+
Next, we need to add files to the `lib/hello_web/controllers/hello_html` directory. A template file has the following structure: `NAME.FORMAT.TEMPLATING_LANGUAGE`. In our case, let's create an `index.html.heex` file at `lib/hello_web/controllers/hello_html/index.html.heex`:
151151

152-
Next, we need to add files to the `lib/hello_web/controllers/hello_html` directory.
152+
```heex
153+
<section>
154+
<h2>Hello World, from Phoenix!</h2>
155+
</section>
156+
```
153157

154-
Note the controller name (`HelloController`), the view name (`HelloHTML`), and the template directory (`hello_html`) all follow the same naming convention and are named after each other. They are also collocated together in the directory tree:
158+
Phoenix will see the template file and compile it into an `index(assigns)` function, similar as before. There is no runtime or performance difference between the two styles.
155159

156-
> **Note**: We can rename the `hello_html` directory to whatever we want and put it in a subdirectory of `lib/hello_web/controllers`, as long as we update the `embed_templates` setting accordingly. However, it's best to keep the same naming convention to prevent any confusion.
160+
Also note the controller name (`HelloController`) and the view name (`HelloHTML`) and their respective files, `hello_controller.ex` and `hello_html.ex` all follow the same naming convention. and are named after each other. You could name the directory anything you want, as long as you update the `embed_templates` setting accordingly, but it's best to follow conventions.
157161

158162
```console
159163
lib/hello_web
160164
├── controllers
161165
│ ├── hello_controller.ex
162166
│ ├── hello_html.ex
163167
│ ├── hello_html
164-
| ├── index.html.heex
168+
| ├── index.html.heex (NEW FILE!)
165169
```
166170

167-
A template file has the following structure: `NAME.FORMAT.TEMPLATING_LANGUAGE`. In our case, let's create an `index.html.heex` file at `lib/hello_web/controllers/hello_html/index.html.heex`:
168-
169-
```heex
170-
<section>
171-
<h2>Hello World, from Phoenix!</h2>
172-
</section>
173-
```
174-
175-
Phoenix will see the template file and compile it into an `index(assigns)` function, similar as before. There is no runtime or performance difference between the two styles.
176-
177171
Now that we've got the route, controller, view, and template, we should be able to point our browser at [http://localhost:4000/hello](http://localhost:4000/hello) and see our greeting from Phoenix!
178172

179173
![Phoenix Greets Us](assets/images/hello-from-phoenix.png)
180174

181175
In case you stopped the server along the way, the task to restart it is `mix phx.server`. If you didn't stop it, everything should update on the fly: Phoenix has hot code reloading!
182176

183-
> A note on hot code reloading: some editors with their automatic linters may prevent hot code reloading from working. If it's not working for you, please see the discussion in [this issue](https://github.com/phoenixframework/phoenix/issues/1165).
184-
185177
## Layouts
186178

187-
188-
189-
Also, even though our `index.html.heex` file consists of only a single `section` tag, the page we get is a full HTML document. Our index template is actually rendered into a separate layout: `lib/hello_web/components/layouts/root.html.heex`, which contains the basic HTML skeleton of the page. If you open this file, you'll see a line that looks like this at the bottom:
179+
Even though our `index.html.heex` file consists of only a single `section` tag, the page we get is a full HTML document. Our index template is actually rendered into a separate layout: `lib/hello_web/components/layouts/root.html.heex`, which contains the basic HTML skeleton of the page. If you open this file, you'll see a line that looks like this at the bottom:
190180

191181
```heex
192182
{@inner_content}
193183
```
194184

195-
This line injects our template into the layout before the HTML is sent off to the browser. We will talk more about layouts in the Controllers guide.
196-
197-
The rest of the page structure is included in the `app` component that is defined in the `lib/hello_web/components/layouts.ex` module.
185+
This line injects our template into the layout before the HTML is sent off to the browser. The root layout, as the name implies, is a barebone layout with mostly the `<head>` tag and a structure that is shared across **all of your pages**. Richer features, such as sidebar, menus, etc. are part of your application layout, which we will explore in a couple sections below.
198186

199187
## From endpoint to views
200188

@@ -293,14 +281,14 @@ If you point your browser to [http://localhost:4000/hello/Frank](http://localhos
293281

294282
![Frank Greets Us from Phoenix](assets/images/hello-world-from-frank.png)
295283

296-
Let's break what the template does into parts. This template has the `.heex` extension. HTML templates in Phoenix are written in HEEx, which stands for (HTML + Embedded Elixir). There are three features from HEEx we are using in the template above:
284+
Let's break what the template does into parts. This template has the `.heex` extension which stands for HTML + Embedded Elixir). There are three features from HEEx we are using in the template above:
297285

298-
* Function components, as in `<Layouts.app>` - they are the essential building block for any kind of markup-based template rendering you'll perform in Phoenix. This particular component will abstract our app layout, such as menu and sidebar, and then render the contents inside
286+
* Assigns, such as `@messenger` and `@flash` - values we pass to the view from the controller are collectively called our "assigns". We could access our messenger value via `assigns.messenger` and `assigns.flash`, but Phoenix gives us the much cleaner `@` syntax for use in templates.
299287

300288
* Content interpolation, such as `{@messenger}` - any Elixir code that goes between `{...}` will be executed, and the resulting value will replace the tag in the HTML output
301289

302-
* Assigns, such as `@messenger` and `@flash` - values we pass to the view from the controller are collectively called our "assigns". We could access our messenger value via `assigns.messenger` and `assigns.flash`, but Phoenix gives us the much cleaner `@` syntax for use in templates.
290+
* Function component tags, as in `<Layouts.app>` - the reason templates are called function components is because we can compose them! In this case, there is an `HelloWeb.Layouts.app` function, that defines our application layout, which we invoke with our custom content
303291

304-
Also note how these three features compose: we are passing the `@flash` assign as an Elixir value to the `<Layouts.app>` component. As we will learn later, flash messages are used to display temporary messages to the user, such as success or error messages.
292+
Also note how these three features compose: we are passing the `@flash` assign as an Elixir value to the `<Layouts.app>` component. As we will learn later, flash messages are used to display temporary messages to the user, such as success or error messages. We will learn more about them in the [Components and HEEx templates](components.html) guide.
305293

306294
We are done! Feel free to play around a bit. Whatever you put after `/hello/` will appear on the page as your messenger.

guides/routing.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -184,8 +184,8 @@ Notice how the first call to an existing route, `~p"/comments"` gave no warning,
184184
Phoenix projects are set up out of the box to allow use of verified routes throughout your web layer, including tests. For example in your templates you can render `~p` links:
185185

186186
```heex
187-
<.link href={~p"/"}>Welcome Page!</.link>
188-
<.link href={~p"/comments"}>View Comments</.link>
187+
<a href={~p"/"}>Welcome Page!</a>
188+
<a href={~p"/comments"}>View Comments</a>
189189
```
190190

191191
Or in a controller, issue a redirect:

lib/phoenix/verified_routes.ex

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ defmodule Phoenix.VerifiedRoutes do
77
For example, the following path and URL usages:
88
99
~H"""
10-
<.link href={~p"/sessions/new"} method="post">Log in</.link>
10+
<a href={~p"/sessions/new"}>Log in</a>
1111
"""
1212
1313
redirect(to: url(~p"/posts/#{post}"))

0 commit comments

Comments
 (0)