やってみよう!Elixir / Phoenix 関数型プログラミングの基礎③

webアプリ開発
目次

コントローラーモジュールとアクション

ターミナルに表示されたメッセージを見てみましょう。

[info] GET /
[debug] Processing with PhxSampleWeb.PageController.home/2
  Parameters: %{}
  Pipelines: [:browser]
[info] Sent 200 in 63ms

ブラウザからGETメソッドにより/へのHTTPリクエストがあり、「成功」を意味するレスポンスコード200を付けてブラウザにHTML文書を返しています。

内容を確認すると2行目に書かれている、[debug] Processing with PhxSampleWeb.PageController.home/2 は、このリクエストを処置した関数の名前を示しています。この関数は次のように定義されています。

defmodule PhxSampleWeb.PageController do
  use PhxSampleWeb, :controller

  def home(conn, _params) do
    # The home page is often custom made,
    # so skip the default app layout.
    render(conn, :home, layout: false)
  end
end

PhxSampleWeb.PageControllerのようにHTTPリクエストを処理するための関数群を持つモジュールをコントローラーモジュールと呼びます。また、関数home/2のようにHTTPリクエストを処理するための関数をアクションと呼びます。

アクションのアリティ(引数の個数)は2で、第1引数にはPlug.Conn構造体を、第2引数にはリクエストパラメーターを格納したマップを取ります。

HEExテンプレート

関数PageController.home/2は次のように定義されています。

def home(conn, _params) do
  # The home page is often custom made,
  # so skip the default app layout.
  render(conn, :home, layout: false)
end

関数render/3は、第2引数に指定されたテンプレートを用いてHTML文書などを生成して返します。テンプレートとしてアトム:homeが指定されています。

 

この場合、lib/phx_sample_web/controllers/page_controller.exディレクトリにある、home.html.heexという名前のファイルがテンプレートとして利用されることになります。コントローラーモジュールの名前がPageControllerであることからディレクトリ名のpage_html

が決まり、アトム:homeからファイル名のhome.html.heexが決まります。

rootレイアウトとappレイアウト

lib/phx_sample_web/components/layoutsディレクトリにroot.html.heexapp.html.heexという名前のファイルがあります。これをrootレイアウトとappレイアウトと呼びます。

rootレイアウト

root.html.heexは、home.html.heexのような普通のテンプレートを埋め込んでHTML文書を完成させるための特別なテンプレートです。

<body class="bg-white">
  <%= @inner_content %>
</body>

bodyタグの部分に@{inner_content}という記述があります。普通のテンプレートはこの場所に埋め込まれています。

appレイアウト

app.html.heexは、適用する場合、普通のテンプレートをappレイアウトに埋め込み、appレイアウトをrootレイアウトに埋め込むという要領でHTML文書が作られます。

<main class="px-4 py-20 sm:px-6 lg:px-8">
  <div class="mx-auto max-w-2xl">
    <.flash_group flash={@flash} />
    <%= @inner_content %>
  </div>
</main>

mainタグの中に<%= @inner_content %>という記述があります。普通のテンプレートはこの場所に埋め込まれます。

ここで、関数PageController.home/2のコードをもう一度見てください。

def home(conn, _params) do
  # The home page is often custom made,
  # so skip the default app layout.
  render(conn, :home, layout: false)
end

関数 render/3layout: false というオプション引数が指定されています。これは「app レイアウトを適用しない」という意味を持ちます。つまり、home アクションが返す HTML 文書は、root レイアウトにテンプレートファイル home.html.heex を直接埋め込むことによって生成されます。