Function Plugs and Module Plugs
April 22, 2022 2 minutes • 313 words
Table of contents
A Plug manipulates data in conn
structs. It’s a Module that has a ‘Conn’ Struct. It takes and returns that conn struct between modules.
It allows state management when combined with Agents and Genservers (like Live View). The state is held by the struct and then is passed between Modules. The ability to pass data turns Plugs into Elixir webservers
It has two types:
- Module Plug
- Function Plug
These are functions that get a Plug.Conn
struct and give a Plug.Conn
struct.
Module Plugs
These need to be initialized.
This is a large function, as a Module, that needs to be initialized with additional data such as state (i.e. initial state). This makes it more complicated than a function plug
Setting
defmodule App.Modulename do
import Plug.Conn
def init(options) do
options
end
def call(conn, _options) do
end
end
Calling
alias ModulePlugName
plug ModulePlugName, [option: "Blah"] when action is [:index]
Controller
alias Appname.Plugname
plug
function_name.(1,2,3,4)
Function Plugs
These add a conn
to a Module function. It is a simple function that receives a conn
struct, manipulates it, and outputs the modified conn struct
How to Create Function Plugs
- Create new Module “test” with
import Plug.conn
- Write the function
def function_plug(conn, _options)
that usesassign()
- In the controller, use that Function Plug Module by importing it
- Call function
plug :blah
- Render it in the view with
<%= @conn.assigns[:blah] %>
Function Plugs take 2 items:
conn
options
If data is available in conn
then use function plugs.
Calling
defmodule App.TotalController do
import App.ModuleName
plug :get_total
..
end
Setting non_piped
and piped
Function Plugs
defmodule App.ModuleName do
import Plug.Conn
def non_pipe(conn, options) do
assign(conn, :non_pipe, 123)
end
def piped(conn, _options) do
conn
|> put_resp_content_type("text/plain")
|> send_resp(200, "From a Piped Function Plug that outputted this data inside this conn struct")
end
end
Calling in Elixir
plug :non_piped
Calling in Phoenix View
<%= @conn.assigns[:non_piped] %>
<%= @non_piped %>
Assigns
assign(key: "#{data.attrib}")