A simple plug to allow setting variables in a connection. For example, as a way to set default variables for a controller, view or template to use in a Phoenix app.
The package can be installed from Hex:
Add plug_assign to your list of dependencies in mix.exs
:
def deps do
[{:plug_assign, "~> 2.0.2"}]
end
Fetch and install the dependencies
$ mix deps.get
Define assigns as part of any plug stack.
plug Plug.Assign, foo: "bar", bar: true, baz: 42
This will set the given key/value pairs in the assigns
map of the Plug.Conn, for you to use
in controllers, views, and templates.
One way to use this is to set variables so you can quickly determine where you are in your app.
pipeline :browser do
...
plug Plug.Assign, admin: false
end
pipeline :admin do
plug Plug.Assign, admin: true
end
And then use that in a template, such as your layout.
<%= if @admin do %>
<p>Hello, Administrator</p>
<% end %>
Since you can use this anywhere you can use a plug, you can also use it in a Phoenix Controller.
defmodule HelloWeb.Admin.PostController do
use HelloWeb, :controller
plug Plug.Assign, section: :posts
...
end
<h1><%= @section %></h1>
If you want to only assign a variable for certain actions, you can use the plug ... when
format,
but be careful that bare keyword lists are only accepted as the last arguments of a macro call,
which is no longer the case with a when
clause, so add the square brackets []
around your
assigns, or use a map instead.
defmodule HelloWeb.Admin.PostController do
use HelloWeb, :controller
plug Plug.Assign, [read_request: true] when action in [:index, :show]
plug Plug.Assign, %{write_request: true} when action in [:edit, :new, :create, :update, :delete]
...
end
If you're using an assign in a template that may not have been set, you can't use the
@variable
format without throwing an error, so use one of the following techniques instead:
- Access shortcut:
assigns[:admin]
- Returnsnil
if not set. - Map.get/2:
Map.get(assigns, :admin)
- Returnsnil
if not set. - Map.get/3:
Map.get(assigns, :admin, false) -
Returnsfalse
if not set.
<%= if assigns[:admin] do %>
<p>Hello, Administrator</p>
<% end %>
Assigns can be either a keyword list
plug Plug.Assign, foo: "bar", bar: true, baz: 42
Or a map, as long as the keys are atoms.
plug Plug.Assign, %{foo: "foo", bar: true, baz: 42}
plug Plug.Assign, %{:foo => "foo", :bar => true, :baz => 42}
Any attempt to pass it anything else will throw an exception.
** (ArgumentError) Invalid assignment, must be a keyword list or map with all keys as atoms
mix docs