Function Plugs and Module Plugs
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:
connoptions
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}")