LoginSignup
3
4

More than 5 years have passed since last update.

Phoenixガイドラインを読んでみた(2) - Adding Pages -

Last updated at Posted at 2016-04-19

はじめに

前回mix phoenix.newで作ったアプリケーションのパスを覗いてみました。
今回は、Phoenix公式ページのAdding Pagesを見ながら、ページを追加していきます。
なお、次回はガイドラインのRoutingです。

追加している書物

New Route

初期状態で、ルーティングを設定するファイルはweb/router.exにあります。
このファイルでは、HTTPメソッドとパスを、ControllerとActionにマッピングすることでルーティングを表します。
前回のデフォルトページの例だと以下のようになります。

get "/", PageController, :index

これは、GETメソッドでルート(/)パスへアクセスを、HelloPhoenix.PageController(web/controllers/page_controller.ex)のindexにマッピングしていることを表します。

では、/helloへのGETアクセスを、HelloPhoenix.HelloControllerのindexにマッピングしてみます。
web/router.exのscopeに、get "/hello", HelloController, :indexを追加します。
scopeやpipelineについては、ひとまずおいておきます。

  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    get "/hello", HelloController, :index
  end

New Controller

Phoenixで言うControllerとはElixirのモジュールであり、ActionはElixirの関数です。
したがって、前項で追加したルーティングのControllerとActionは次のようになります(web/controllers/hello_controller.ex)。

defmodule HelloPhoenix.HelloController do
  use HelloPhoenix.Web, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end
end

index/2関数の最初の引数connは、リクエストに関するさまざまな情報が含まれています。
二つ目の引数_paramsは、リクエストパラメータが格納されます。今回は参照しないので、先頭に"_"を付けておきます。

このアクションの中身render conn, "index.html"は、テンプレートindex.html.eexを探してレンダリングすることを表しています。
このファイルは、テンプレートディレクトリの後にコントローラの名前を追加したディレクトリ(web/templates/hello/)から探されます。

なお、render conn, :indexとアトムを使うこともできますが、この場合は、acceptヘッダ応じてindex.htmlやindex.jsonなどのテンプレートが選択されます。

New View

PhoenixではレンダリングはViewの仕事です。
Viewでは、Controllerからレンダリングに必要なデータを受け取り、表示用に変換し、テンプレートに適用して表示するといった作業を行います。

前述作成したHelloControllerに対してはHelloViewを用意する必要があります。なお、Viewの前の名前(Hello)は、Controllerと一致しておく必要があります。
HelloViewは、web/views/hello_view.exに以下のように作成することにします。

defmodule HelloPhoenix.HelloView do
  use HelloPhoenix.Web, :view
end

New Template

Phoenixでは、標準のテンプレートとしてEExを使用します。
Templateは、テンプレートディレクトリ(web/templates/)に後にControllerの名前(hello)を追加したディレクトリ(web/templates/hello)に配置します。テンプレート名はControllerで定義(index.html)したファイルに拡張し(.eex)を追加したファイルになります(web/templates/hello/index.html.eex)。

<div class="jumbotron">
  <h2>Hello World, from Phoenix!</h2>
</div>

Phoenixサーバを起動(mix phoenix.server)して、ブラウザでlocalhost:4000/helloにアクセスしてみます。なお、Phoenixサーバを起動しっぱなしだった場合でも、再起動する必要はありません。アクセスされたときに必要であれば再ビルドされます。

index.html.eexにはdivしかありません。html本体はweb/templates/layout/app.html.eexにあり、このファイル内の以下の部分にindex.html.eexの内容が差し込まれます。

      <main role="main">
        <%= render @view_module, @view_template, assigns %>
      </main>

もう一つアクション

もう一つ、URLの一部に"messenger"という名前を付けて、パラメータとしてControllerに渡して、そのパラメータを含むページを表示する例を作成します。

New Route2

Routeにパラメータを表すアトム":messenger"を追加した行を追加します。
URLでアトムに対応する部分がパラメータとしてControllerに渡されます。
例えば、以下のRouteに対してlocalhost:4000/hello/Hogehogeを与えると、パラメータ"messenger"に"hogehoge"が割り当てられます。

  scope "/", HelloPhoenix do
    pipe_through :browser # Use the default browser stack

    get "/", PageController, :index
    get "/hello", HelloController, :index
    get "/hello/:messenger", HelloController, :show
  end

New Action2

web/controllers/hello_controller.exはすでに作成済みですので、これにshow Actionを追加します(:showは前項でRouteに追加したAction)。
show関数の第二引数はパターンマッチングで実装しています。

def show(conn, %{"messenger" => messenger}) do
  render conn, "show.html", messenger: messenger
end

Controllerのrender/3は、第三引数にパラメータを渡すことができ、そのパラメータはViewに渡されます。

New Template2

show Actionに対応するTemplate(web/templates/hello/show.html.eex)を作成します。
EExには、<%= %>内にElixirの式を書くことができます。
なお、@messengerは、テンプレートで使用できるメタプログラミングな書き方で、Dict.get(assigns, :messenger)と同じ意味です。これによりシンプルにパラメータを表現することができます。

<div class="jumbotron">
  <h2>Hello World, from <%= @messenger %>!</h2>
</div>

これでlocalhost:4000/hello/hogehogeなどとアクセスすると、"Hello World, from hogehoge!"とブラウザに表示されることになります。

3
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
4