Repository: phoenixframework/phoenix
Pull request #4179 (2021-01-25 20:27:16)

Fix bug in Plug guide code
We will get an error when loading http://localhost:4000/,

```
 ArgumentError at GET /
assign @locale not available in eex template.
```

It is the PageController, not the HelloController where the plug needs to go.


Patch:
diff --git a/guides/contexts.md b/guides/contexts.md
index 52ef7b499..a3cd33661 100644
--- a/guides/contexts.md
+++ b/guides/contexts.md
@@ -1,6 +1,6 @@
 # Contexts
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Request life-cycle guide](request_lifecycle.html).
 
diff --git a/guides/controllers.md b/guides/controllers.md
index 6f27eb06f..4ca3df4f7 100644
--- a/guides/controllers.md
+++ b/guides/controllers.md
@@ -1,6 +1,6 @@
 # Controllers
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Request life-cycle guide](request_lifecycle.html).
 
diff --git a/guides/directory_structure.md b/guides/directory_structure.md
index 51690c150..d678f78bc 100644
--- a/guides/directory_structure.md
+++ b/guides/directory_structure.md
@@ -1,6 +1,6 @@
 # Directory structure
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 When we use `mix phx.new` to generate a new Phoenix application, it builds a top-level directory structure like this:
 
@@ -20,7 +20,7 @@ When we use `mix phx.new` to generate a new Phoenix application, it builds a top
 
 We will go over those directories one by one:
 
-  * `_build` - a directory created by the `mix` command line tool that ships as part of Elixir that holds all compilation artifacts. As we have seen in "Up and Running", `mix` is the main interface to your application. We use Mix to compile our code, create databases, run our server, and more. This directory must not be checked into version control and it can be removed at any time. Removing it will force Mix to rebuild your application from scratch
+  * `_build` - a directory created by the `mix` command line tool that ships as part of Elixir that holds all compilation artifacts. As we have seen in "[Up and Running](up_and_running.html)", `mix` is the main interface to your application. We use Mix to compile our code, create databases, run our server, and more. This directory must not be checked into version control and it can be removed at any time. Removing it will force Mix to rebuild your application from scratch
 
   * `assets` - a directory that keeps everything related to front-end assets, such as JavaScript, CSS, static images and more. It is typically handled by the `npm` tool. Phoenix developers typically only need to run `npm install` inside the assets directory. Everything else is managed by Phoenix
 
@@ -65,7 +65,7 @@ If it is your first time with Phoenix, you don't need to worry about the details
 
 You can learn more about applications in [Elixir's official docs for Application](https://hexdocs.pm/elixir/Application.html).
 
-In the same `lib/hello` directory, we will find a `lib/hello/repo.ex`. It defines a `Hello.Repo` module which is our main interface to the database. If you are using Postgres (the default), you will see something like this:
+In the same `lib/hello` directory, we will find a `lib/hello/repo.ex`. It defines a `Hello.Repo` module which is our main interface to the database. If you are using Postgres (the default database), you will see something like this:
 
 ```elixir
 defmodule Hello.Repo do
@@ -103,13 +103,13 @@ lib/hello_web
 └── telemetry.ex
 ```
 
-All of the files which are currently in the `controllers`, `templates`, and `views` directories are there to create the "Welcome to Phoenix!" page we saw in the "Up and running" guide.
+All of the files which are currently in the `controllers`, `templates`, and `views` directories are there to create the "Welcome to Phoenix!" page we saw in the "[Up and running](up_and_running.html)" guide.
 The `channels` directory is where we will add code related to building real-time Phoenix applications.
 
 By looking at `templates` and `views` directories, we can see Phoenix provides features for handling layouts and error pages out of the box.
 
-Besides the directories mentioned, `lib/hello_web` has four files at its root. `lib/hello_web/endpoint.ex` is the entry-point for HTTP requests. Once the browser accesses `http://localhost:4000`, the endpoint starts processing the data, eventually leading to the router, which is defined in `lib/hello_web/router.ex`. The router defines the rules to dispatch requests to "controllers", which then uses "views" and "templates" to render HTML pages back to clients. We explore these layers in length in other guides, starting with the "Request life-cycle" guide coming next.
+Besides the directories mentioned, `lib/hello_web` has four files at its root. `lib/hello_web/endpoint.ex` is the entry-point for HTTP requests. Once the browser accesses [http://localhost:4000](http://localhost:4000), the endpoint starts processing the data, eventually leading to the router, which is defined in `lib/hello_web/router.ex`. The router defines the rules to dispatch requests to "controllers", which then uses "views" and "templates" to render HTML pages back to clients. We explore these layers in length in other guides, starting with the "[Request life-cycle](request_lifecycle.html)" guide coming next.
 
-Through _telemetry_, Phoenix is able to collect metrics and send monitoring events of your application. The `lib/hello_web/telemetry.ex` file defines the supervisor responsible for managing the telemetry processes. You can find more information on this topic in the [Telemetry guide](telemetry.html).
+Through _Telemetry_, Phoenix is able to collect metrics and send monitoring events of your application. The `lib/hello_web/telemetry.ex` file defines the supervisor responsible for managing the telemetry processes. You can find more information on this topic in the [Telemetry guide](telemetry.html).
 
 Finally, there is a `lib/hello_web/gettext.ex` file which provides internationalization through [Gettext](https://hexdocs.pm/gettext/Gettext.html). If you are not worried about internationalization, you can safely skip this file and its contents.
diff --git a/guides/ecto.md b/guides/ecto.md
index 957b5c073..fdf83fe53 100644
--- a/guides/ecto.md
+++ b/guides/ecto.md
@@ -1,6 +1,6 @@
 # Ecto
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 Most web applications today need some form of data validation and persistence. In the Elixir ecosystem, we have Ecto to enable this. Before we jump into building database-backed web features, we're going to focus on the finer details of Ecto to give a solid base to build our web features on top of. Let's get started!
 
diff --git a/guides/plug.md b/guides/plug.md
index 8a8dd6ec9..88e3b73f1 100644
--- a/guides/plug.md
+++ b/guides/plug.md
@@ -1,6 +1,6 @@
 # Plug
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Request life-cycle guide](request_lifecycle.html).
 
@@ -72,7 +72,7 @@ Module plugs are another type of Plug that let us define a connection transforma
 - `init/1` which initializes any arguments or options to be passed to `call/2`
 - `call/2` which carries out the connection transformation. `call/2` is just a function plug that we saw earlier
 
-To see this in action, let's write a module plug that puts the `:locale` key and value into the connection assign for downstream use in other plugs, controller actions, and our views. Put the contents above to a file named "lib/hello_web/plugs/locale.ex":
+To see this in action, let's write a module plug that puts the `:locale` key and value into the connection assign for downstream use in other plugs, controller actions, and our views. Put the contents above to a file named `lib/hello_web/plugs/locale.ex`:
 
 ```elixir
 defmodule HelloWeb.Plugs.Locale do
@@ -111,7 +111,7 @@ defmodule HelloWeb.Router do
 
 We are able to add this module plug to our browser pipeline via `plug HelloWeb.Plugs.Locale, "en"`. In the `init/1` callback, we pass a default locale to use if none is present in the params. We also use pattern matching to define multiple `call/2` function heads to validate the locale in the params, and fall back to "en" if there is no match.
 
-To see the assign in action, go to the layout in "lib/hello_web/templates/layout/app.html.eex" and add the following close to the main container:
+To see the assign in action, go to the layout in `lib/hello_web/templates/layout/app.html.eex` and add the following close to the main container:
 
 ```html
 <main role="main" class="container">
@@ -202,7 +202,7 @@ As we will see in [the Routing guide](routing.html), the pipelines themselves ar
 Finally, controllers are plugs too, so we can do:
 
 ```elixir
-defmodule HelloWeb.HelloController do
+defmodule HelloWeb.PageController do
   use HelloWeb, :controller
 
   plug HelloWeb.Plugs.Locale, "en"
@@ -211,7 +211,7 @@ defmodule HelloWeb.HelloController do
 In particular, controller plugs provide a feature that allows us to execute plugs only within certain actions. For example, you can do:
 
 ```elixir
-defmodule HelloWeb.HelloController do
+defmodule HelloWeb.PageController do
   use HelloWeb, :controller
 
   plug HelloWeb.Plugs.Locale, "en" when action in [:index]
diff --git a/guides/realtime/channels.md b/guides/realtime/channels.md
index 82f581d88..b2b2a790a 100644
--- a/guides/realtime/channels.md
+++ b/guides/realtime/channels.md
@@ -1,6 +1,6 @@
 # Channels
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 Channels are an exciting part of Phoenix that enable soft real-time communication with and between millions of connected clients.
 
diff --git a/guides/realtime/presence.md b/guides/realtime/presence.md
index 80bdb0b1b..795cd60cf 100644
--- a/guides/realtime/presence.md
+++ b/guides/realtime/presence.md
@@ -1,6 +1,6 @@
 # Presence
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Channels guide](channels.html).
 
diff --git a/guides/request_lifecycle.md b/guides/request_lifecycle.md
index 568f8bb87..db9ea3207 100644
--- a/guides/request_lifecycle.md
+++ b/guides/request_lifecycle.md
@@ -1,6 +1,6 @@
 # Request life-cycle
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 The goal of this guide is to talk about Phoenix's request life-cycle. This guide will take a practical approach where we will learn by doing: we will add two new pages to our Phoenix project and comment on how the pieces fit together along the way.
 
@@ -101,13 +101,13 @@ We'll save a discussion of `use HelloWeb, :controller` for the [Controllers Guid
 
 All controller actions take two arguments. The first is `conn`, a struct which holds a ton of data about the request. The second is `params`, which are the request parameters. Here, we are not using `params`, and we avoid compiler warnings by adding the leading `_`.
 
-The core of this action is `render(conn, "index.html")`. It tells Phoenix to render "index.html". The modules responsible for rendering are called views. By default, Phoenix views are named after the controller, so Phoenix is expecting a `HelloWeb.HelloView` to exist and handle "index.html" for us.
+The core of this action is `render(conn, "index.html")`. It tells Phoenix to render `"index.html"`. The modules responsible for rendering are called views. By default, Phoenix views are named after the controller, so Phoenix is expecting a `HelloWeb.HelloView` to exist and handle `"index.html"` for us.
 
 > Note: Using an atom as the template name also works `render(conn, :index)`. In these cases, the template will be chosen based off the Accept headers, e.g. `"index.html"` or `"index.json"`.
 
 ### A new View
 
-Phoenix views act as the presentation layer. For example, we expect the output of rendering "index.html" to be a complete HTML page. To make our lives easier, we often use templates for creating those HTML pages.
+Phoenix views act as the presentation layer. For example, we expect the output of rendering `"index.html"` to be a complete HTML page. To make our lives easier, we often use templates for creating those HTML pages.
 
 Let's create a new view. Create `lib/hello_web/views/hello_view.ex` and make it look like this:
 
@@ -119,7 +119,7 @@ end
 
 Now in order to add templates to this view, we simply need to add files to the `lib/hello_web/templates/hello` directory. Note the controller name (`HelloController`), the view name (`HelloView`), and the template directory (`hello`) all follow the same naming convention and are named after each other.
 
-A template file has the following structure: `NAME.FORMAT.TEMPLATING_LANGUAGE`. In our case, we will create a "index.html.eex" file at "lib/hello_web/templates/hello/index.html.eex". ".eex" stands for `EEx`, which is a library for embedding Elixir that ships as part of Elixir itself. Phoenix enhances EEx to include automatic escaping of values. This protects you from security vulnerabilities like Cross-Site-Scripting with no extra work on your part.
+A template file has the following structure: `NAME.FORMAT.TEMPLATING_LANGUAGE`. In our case, we will create a `index.html.eex` file at `lib/hello_web/templates/hello/index.html.eex`. ".eex" stands for `EEx`, which is a library for embedding Elixir that ships as part of Elixir itself. Phoenix enhances EEx to include automatic escaping of values. This protects you from security vulnerabilities like Cross-Site-Scripting with no extra work on your part.
 
 Create `lib/hello_web/templates/hello/index.html.eex` and make it look like this:
 
diff --git a/guides/routing.md b/guides/routing.md
index 7ae6d3a88..5e0d03364 100644
--- a/guides/routing.md
+++ b/guides/routing.md
@@ -1,6 +1,6 @@
 # Routing
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Request life-cycle guide](request_lifecycle.html).
 
diff --git a/guides/views.md b/guides/views.md
index 0339f5fc7..02ffad229 100644
--- a/guides/views.md
+++ b/guides/views.md
@@ -1,6 +1,6 @@
 # Views and templates
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Request life-cycle guide](request_lifecycle.html).
 
@@ -220,7 +220,7 @@ defmodule HelloWeb.PageView do
 end
 ```
 
-In the view we see our `render/2` function pattern matching on `"index.json"`, `"show.json"`, and `"page.json"`. The "index.json" and "show.json" are the ones requested directly from the controller. They also match on the assigns sent by the controller. `"index.json"` will respond with JSON like this:
+In the view we see our `render/2` function pattern matching on `"index.json"`, `"show.json"`, and `"page.json"`. The `"index.json"` and `"show.json"` are the ones requested directly from the controller. They also match on the assigns sent by the controller. `"index.json"` will respond with JSON like this:
 
 ```javascript
 {
@@ -245,7 +245,7 @@ And the `render/2` matching `"show.json"`:
 }
 ```
 
-This works because both "index.json" and "show.json" build themselves on top of an internal "page.json" clause.
+This works because both `index.json` and `show.json` build themselves on top of an internal `page.json` clause.
 
 The `render_many/3` function takes the data we want to respond with (`pages`), a view, and a string to pattern match on the `render/2` function defined on view. It will map over each item in `pages` and call `PageView.render("page.json", %{page: page})`. `render_one/3` follows the same signature, ultimately using the `render/2` matching `page.json` to specify what each `page` looks like.
 


Test patch:
diff --git a/guides/testing/testing.md b/guides/testing/testing.md
index 8d3fc2da5..7bf19ac96 100644
--- a/guides/testing/testing.md
+++ b/guides/testing/testing.md
@@ -1,6 +1,6 @@
 # Introduction to Testing
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 Testing has become integral to the software development process, and the ability to easily write meaningful tests is an indispensable feature for any modern web framework. Phoenix takes this seriously, providing support files to make all the major components of the framework easy to test. It also generates test modules with real-world examples alongside any generated modules to help get us going.
 
diff --git a/guides/testing/testing_channels.md b/guides/testing/testing_channels.md
index e996d7874..7826a6b1b 100644
--- a/guides/testing/testing_channels.md
+++ b/guides/testing/testing_channels.md
@@ -1,6 +1,6 @@
 # Testing Channels
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Introduction to Testing guide](testing.html).
 
@@ -77,7 +77,7 @@ setup do
 end
 ```
 
-The `setup` block sets up a `Phoenix.Socket` based on the `UserSocket` module, which you can find at "lib/hello_web/channels/user_socket.ex". Then it says we want to subscribe and join the `RoomChannel`, accessible as "room:lobby" in the `UserSocket`. At the end of the test, we return the `%{socket: socket}` as metadata, so we can reuse it on every test.
+The `setup` block sets up a `Phoenix.Socket` based on the `UserSocket` module, which you can find at `lib/hello_web/channels/user_socket.ex`. Then it says we want to subscribe and join the `RoomChannel`, accessible as `"room:lobby"` in the `UserSocket`. At the end of the test, we return the `%{socket: socket}` as metadata, so we can reuse it on every test.
 
 In a nutshell, `subscribe_and_join/3` emulates the client joining a channel and subscribes the test process to the given topic. This is a necessary step since clients need to join a channel before they can send and receive events on that channel.
 
diff --git a/guides/testing/testing_contexts.md b/guides/testing/testing_contexts.md
index 632ebdec5..6b387f8ef 100644
--- a/guides/testing/testing_contexts.md
+++ b/guides/testing/testing_contexts.md
@@ -1,6 +1,6 @@
 # Testing Contexts
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Introduction to Testing guide](testing.html).
 
diff --git a/guides/testing/testing_controllers.md b/guides/testing/testing_controllers.md
index 798cf56bd..7480c47e1 100644
--- a/guides/testing/testing_controllers.md
+++ b/guides/testing/testing_controllers.md
@@ -1,6 +1,6 @@
 # Testing Controllers
 
-> **Requirement**: This guide expects that you have gone through the introductory guides and got a Phoenix application up and running.
+> **Requirement**: This guide expects that you have gone through the [introductory guides](installation.html) and got a Phoenix application [up and running](up_and_running.html).
 
 > **Requirement**: This guide expects that you have gone through [the Introduction to Testing guide](testing.html).
 
@@ -101,7 +101,7 @@ describe "create post" do
 end
 ```
 
-The first test starts with a `post/2` request. That's because once the form in the "/posts/new" page is submitted, it becomes a POST request to the create action. Because we have supplied valid attributes, the post should have been successfully created and we should have redirected to the show action of the new post. This new page will have an address like "/posts/ID", where ID is the identifier of the post in the database.
+The first test starts with a `post/2` request. That's because once the form in the `/posts/new` page is submitted, it becomes a POST request to the create action. Because we have supplied valid attributes, the post should have been successfully created and we should have redirected to the show action of the new post. This new page will have an address like `/posts/ID`, where ID is the identifier of the post in the database.
 
 We then use `redirected_params(conn)` to get the ID of the post and then match that we indeed redirected to the show action. Finally, we do request a `get` request to the page we redirected to, allowing us to verify that the post was indeed created.
 
@@ -185,7 +185,7 @@ end
   1. An exception was raised
   2. The exception has a status code equivalent to 404 (which stands for Not Found)
 
-This pretty much mimics how Phoenix handles exceptions. For example, when we access "/posts/12345" where 12345 is an ID that does not exist, we will invoke our `show` action:
+This pretty much mimics how Phoenix handles exceptions. For example, when we access `/posts/12345` where `12345` is an ID that does not exist, we will invoke our `show` action:
 
 ```elixir
 def show(conn, %{"id" => id}) do
@@ -255,7 +255,7 @@ def index(conn, _params) do
 end
 ```
 
-The action gets all articles and renders "index.json". Since we are talking about JSON, we don't have a "index.json.eex" template. Instead, the code that converts "articles" into JSON can be found directly in the ArticleView module, defined at `lib/hello_web/views/article_view.ex` like this:
+The action gets all articles and renders `index.json`. Since we are talking about JSON, we don't have a `index.json.eex` template. Instead, the code that converts `articles` into JSON can be found directly in the ArticleView module, defined at `lib/hello_web/views/article_view.ex` like this:
 
 ```elixir
 defmodule HelloWeb.ArticleView do