Controller
Phoenix adopt an architectural pattern similar to the MVC pattern.
In controller we need to find out:
- How to access request data, like headers, body and query parameters.
- How to invoke models.
- How to render template.
Take a look at lib/app1_web/controllers/page_controller.ex:
defmodule App1Web.PageController do
use App1Web, :controller
def home(conn, _params) do
render(conn, :home, layout: false)
end
end
Take a look at lib/app1_web.ex:
def controller do
quote do
use Phoenix.Controller,
formats: [:html, :json],
layouts: [html: App1Web.Layouts]
use Gettext, backend: App1Web.Gettext
import Plug.Conn
unquote(verified_routes())
end
end
Accessing Request Data
_params is a map of query string and form inputs:
def home(conn, _params) do
render(conn, :home, layout: false)
end
Try to add query string with curl:
curl 'localhost:4000?key=1&key=2'
It will be printed on the command line:
[debug] Processing with App1Web.PageController.home/2
Parameters: %{"key" => 2}
Pipelines: [:browser]
See if array works:
curl 'localhost:4000?key[]=1&key[]=2'
%{"key" => ["1", "2"]}
Add a routing rule for POST in router.ex:
post "/", PageController, :home
curl -d 'foo=bar' 'localhost:4000?key[]=1&key[]=2'
%{"foo" => "bar", "key" => ["1", "2"]}
JSON also works:
curl -d '{"ok":true}' -H 'content-type: application/json' \
'localhost:4000?key[]=1&key[]=2'
%{"key" => ["1", "2"], "ok" => true}
Rendering Template
The controler simply called render, add passed :home.
In lib/app1_web/controllers/page_html.ex, it doesn't do much, just
called embed_templates and passed the director path.
defmodule App1Web.PageHTML do
use App1Web, :html
embed_templates "page_html/*"
end
The embed_templates macro expands to following:
def home(assigns) do
~H"""
<.flash_group flash={@flash} />
...
"""
end
And the home function will be called by render.