前回 の続き
https://hexdocs.pm/phoenix/adding_pages.html#content
に沿ってページの追加やっていきます。
静的ページの追加
パスからコントローラへのルーティングを追加します。
scope "/", HelloWeb do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
get "/hello", HelloController, :index # ★追加
end
んでコントローラも作ります。
defmodule HelloWeb.HelloController do
use HelloWeb, :controller
def index(conn, _params) do
render conn, "index.html"
end
end
connにはリクエストの情報やらレスポンスに使う情報やらが格納されています。
https://hexdocs.pm/plug/Plug.Conn.html
paramは今回使わないので、"_"付き
続いてビュー側。
Viewとtemplateを作成します。
defmodule HelloWeb.HelloView do
use HelloWeb, :view
end
<div class="jumbotron">
<h2>Hello World, from Phoenix!</h2>
</div>
表示用にデータの加工したりするのがView、
実際に表示するhtmlを組み立てるのがtemplateです。
controllerからはindex.htmlとしか指定してないですが、パスは名前で解決される模様。
templateの割にいろいろ表示されてますね。
hello/lib/hello_web/templates/layout/app.html.eex を見ると <%= render @view_module, @view_template, assigns %>
といった記述があるので、ここに埋め込まれるみたいですね。
renderはまずlayoutViewから行われるようです。設定とかで変えられるのかな。
この辺の仕組みは後で掘ってみるとして。
動的ページ
次はパラメータを受け取り、それを表示させます。
Controllerは先程のHelloControllerをそのまま使います。
scope "/", HelloWeb do
pipe_through :browser # Use the default browser stack
get "/", PageController, :index
get "/hello", HelloController, :index
get "/hello/:messenger", HelloController, :show # ★追加
end
def show(conn, %{"messenger" => messenger}) do
render conn, "show.html", messenger: messenger
end
<div class="jumbotron">
<h2>Hello World, from <%= @messenger %> !</h2>
</div>
routerで指定した:messengerがマップに入ってコントローラに渡るようです。
これは、つまり、パターンマッチが出来るのか・・・!
いったんAddingPagesは終わりですが、実験。
def show(conn, %{"messenger" => messenger}) when messenger=="utonton" do
render conn, "special.html", messenger: messenger
end
def show(conn, %{"messenger" => messenger}) do
render conn, "show.html", messenger: messenger
end
<div class="jumbotron">
<h2>Hey! You are special message from <%= @messenger %> !</h2>
</div>
・・・できちゃったよ。
これ、意外と便利なんじゃなかろうか。コントローラ内で分岐するよりだいぶスッキリしてる。
しかもコントローラ内で変な分岐入れるのって結構抵抗あるけど、
こういった形なら書きやすいし、何より意図が伝わりやすそう。