Skip to content

Commit cd25050

Browse files
committed
1.0.2 - Added better error handling
1 parent 0d0dc9d commit cd25050

File tree

13 files changed

+168
-106
lines changed

13 files changed

+168
-106
lines changed

.formatter.exs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Used by "mix format"
2+
[
3+
inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"]
4+
]

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ fabric.properties
5050

5151
# Editor-based Rest Client
5252
.idea/httpRequests
53+
5354
### Elixir template
5455
/_build
5556
/cover
@@ -61,3 +62,5 @@ erl_crash.dump
6162
*.beam
6263
/config/*.secret.exs
6364

65+
# VS Code
66+
.elixir_ls

.idea/encodings.xml

Lines changed: 0 additions & 6 deletions
This file was deleted.

.idea/inspectionProfiles/Project_Default.xml

Lines changed: 0 additions & 17 deletions
This file was deleted.

.idea/misc.xml

Lines changed: 0 additions & 10 deletions
This file was deleted.

.idea/modules.xml

Lines changed: 0 additions & 8 deletions
This file was deleted.

.idea/plug_assign.iml

Lines changed: 0 additions & 18 deletions
This file was deleted.

.idea/vcs.xml

Lines changed: 0 additions & 6 deletions
This file was deleted.

README.md

Lines changed: 80 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ Add plug_assign to your list of dependencies in `mix.exs`:
1010

1111
```elixir
1212
def deps do
13-
[{:plug_assign, "~> 1.0.0"}]
13+
[{:plug_assign, "~> 1.0.2"}]
1414
end
1515
```
1616

@@ -20,32 +20,104 @@ Fetch and install the dependencies
2020
$ mix deps.get
2121
```
2222

23-
Define assigns as part of your plug stack
23+
## Basic Usage
24+
25+
Define assigns as part of any plug stack.
2426

2527
```elixir
2628
plug Plug.Assign, foo: "bar", bar: true, baz: 42
2729
```
2830

29-
Or Set variables for templates to use in a Phoenix Pipeline
31+
This will set the given key/value pairs in the `assigns` map of the Plug.Conn, for you to use
32+
in controllers, views, and templates.
33+
34+
One way to use this is to set variables so you can quickly determine where you are in your app.
3035

3136
```elixir
37+
pipeline :browser do
38+
...
39+
plug Plug.Assign, admin: false
40+
end
41+
3242
pipeline :admin do
3343
plug Plug.Assign, admin: true
3444
end
3545
```
3646

37-
Or directly in a Phoenix Controller
47+
And then use that in a template, such as your layout.
48+
49+
```html
50+
<%= if @admin do %>
51+
<p>Hello, Administrator</p>
52+
<% end %>
53+
```
54+
55+
Since you can use this anywhere you can use a plug, you can also use it in a Phoenix Controller.
56+
57+
```elixir
58+
defmodule HelloWeb.Admin.PostController do
59+
use HelloWeb, :controller
60+
61+
plug Plug.Assign, section: :posts
62+
...
63+
end
64+
```
65+
66+
```html
67+
<h1><%= @section %></h1>
68+
```
69+
70+
If you want to only assign a variable for certain actions, you can use the `plug ... when` format,
71+
but be careful that bare keyword lists are only accepted as the last arguments of a macro call,
72+
which is no longer the case with a `when` clause, so add the square brackets `[]` around your
73+
assigns, or use a map instead.
3874

3975
```elixir
40-
defmodule Blog.Admin.PostController do
41-
use Blog.Web, :Controller
76+
defmodule HelloWeb.Admin.PostController do
77+
use HelloWeb, :controller
4278

43-
plug Plug.Assign, subsection: :posts
44-
plug Plug.Assign, %{read_request: true} when action in [:index, :show]
79+
plug Plug.Assign, [read_request: true] when action in [:index, :show]
80+
plug Plug.Assign, %{write_request: true} when action in [:edit, :new, :create, :update, :delete]
4581
...
4682
end
4783
```
4884

85+
## Accessing in templates
86+
87+
If you're using an assign in a template that may not have been set, you can't use the
88+
`@variable` format without throwing an error, so use one of the following techniques instead:
89+
90+
- Access shortcut: `assigns[:admin]` - Returns `nil` if not set.
91+
- Map.get/2: `Map.get(assigns, :admin)` - Returns `nil` if not set.
92+
- Map.get/3: `Map.get(assigns, :admin, false) - `Returns `false` if not set.
93+
94+
```html
95+
<%= if assigns[:admin] do %>
96+
<p>Hello, Administrator</p>
97+
<% end %>
98+
```
99+
100+
## Assignment formats
101+
102+
Assigns can be either a keyword list
103+
104+
```elixir
105+
plug Plug.Assign, foo: "bar", bar: true, baz: 42
106+
```
107+
108+
Or a map, as long as the keys are atoms.
109+
110+
```elixir
111+
plug Plug.Assign, %{foo: "foo", bar: true, baz: 42}
112+
plug Plug.Assign, %{:foo => "foo", :bar => true, :baz => 42}
113+
```
114+
115+
Any attempt to pass it anything else will throw an exception.
116+
117+
```bash
118+
** (ArgumentError) Invalid assignment, must be a keyword list or map with all keys as atoms
119+
```
120+
49121
## Generate documentation
50122

51123
```bash

lib/plug/assign.ex

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ defmodule Plug.Assign do
44
55
## Example
66
7-
plug Plug.Assign, foo: "bar", bar: true, baz: 42
7+
plug Plug.Assign, foo: "foo", bar: true, baz: 42
88
99
## Example of use in a Phoenix Pipeline
1010
@@ -24,14 +24,30 @@ defmodule Plug.Assign do
2424
"""
2525

2626
@behaviour Plug
27+
@invalid_type "Invalid assignment, must be a keyword list or map with all keys as atoms."
2728

2829
import Plug.Conn
30+
require Logger
2931

30-
def init(assigns), do: assigns
32+
def init(assigns) when is_list(assigns) or is_map(assigns), do: assigns
33+
def init(_), do: raise(ArgumentError, message: @invalid_type)
3134

32-
def call(conn, assigns) do
33-
Enum.reduce assigns, conn, fn {k, v}, conn ->
34-
assign(conn, k, v)
35-
end
36-
end
35+
def call(conn, assigns) do
36+
Enum.reduce(assigns, conn, fn
37+
{k, v}, conn when is_atom(k) ->
38+
assign(conn, k, v)
39+
40+
{k, _}, conn ->
41+
Logger.warn("[Plug.Assign] Invalid key: #{inspect(k)}. Keys must be an atom.")
42+
conn
43+
44+
var, conn ->
45+
Logger.warn(
46+
"[Plug.Assign] Invalid assign: #{inspect(var)}. Assigns must be {:key, value}. " <>
47+
"Use a keyword list or a map with all keys as atoms."
48+
)
49+
50+
conn
51+
end)
52+
end
3753
end

0 commit comments

Comments
 (0)