はじめに
前回は、Controllerを見てきました。
今回はViewです。
次回は、ガイドラインのTemplateです。
視界
PhoenixのViewの主な仕事は二つです。重要な方の仕事は、Template(およびLayout)をレンダリングすること。これを行うのは、Phoenix.View
に定義されたrender/3
関数です。もう一つの仕事は、データを取得したりテンプレートにデータを加工する関数を提供することです。
Phoenixは、Controller、View、テンプレートとの間には絶対的な命名規則があり、PageController
に対してはPageView
が必要であり、Templateはweb/templates/page
ディレクトリにある必要があります。
ただし、もし必要であれば、Templateのルートディレクトリは変更することができます。web/web.ex
に定義されているHelloPhoenix.Web
モジュールのview/0
関数で、:root
キーの値を変更することでルートディレクトリを変更することができます。
Phoenixアプリケーションを生成したときには、三つのViewモジュールが生成されます。ErrorView
、LayoutView
、PageView
の三つで、すべて、web/views
ディレクトリにあります。
LayoutViewは、以下のようになっています。非常にシンプルです。
defmodule HelloPhoenix.LayoutView do
use HelloPhoenix.Web, :view
end
HelloPhoenix.Web, :view
は、マクロによってHelloPhoenix.Web
のview/0
関数を呼び出します。ここでルートディレクトリを:root
としてセットしています。
ここで、レイアウトファイルtemplates/layout/app.html.eex
の中の<title>Hello Phoenix</title>
を<title><%= title %></title>
に変更してみます。
次にLayoutViewに関数title/0
を追加します。
defmodule HelloPhoenix.LayoutView do
use HelloPhoenix.Web, :view
def title do
"Hogehoge"
end
end
ここでサーバを起動してアクセスしてみると、タイトルに"Hogehoge"が表示されます。なお、title関数を実装していない場合には、サーバ起動前にコンパイルエラーが発生します。
Viewについてもう少し
Phoenix.Viewモジュールは、内部でuse Phoenix.Template
を呼び出すことでTemplateに関するさまざまな関数などを使用できるようにしています。
ここで新たな例として、PageView (web/views/page_view.ex
)を下のように変更します。
defmodule HelloPhoenix.PageView do
use HelloPhoenix.Web, :view
def message do
"Viewからのメッセージ"
end
end
次にテンプレート(web/templates/page/test.html.eex
)を作成します。
@付きのメッセージ: <%= @message %>
@なしのメッセージ: <%= message %>
今回はブラウザから見るのではなく、直接iexからrender関数を呼び出すことにします。
$ iex -S mix
iex(1) Phoenix.View.render(HelloPhoenix.PageView, "test.html", message: "Renderからのメッセージ")
{:safe,
[[[["" | "@付きのメッセージ: "] | "Renderからのメッセージ"] |
"\n@なしのメッセージ: "] | "Viewからのメッセージ"]}
結果tupleの最初の:safe
atomは、結果の文字列がレンダリング可能な状態になっていることを示しています。
@付きのシンボルは、render/3の第三引数として与えられたMapから展開されます。@無しのシンボルはElixirコードとして解釈されます。
Layoutについて
LayoutはTemplateの一種です。したがって、Template同様にView(web/views/layout_view.ex)を持ちます。 Templateが描画されたとき、LayoutのViewは、@innerに表示されたTemplateの内容が格納されます。この内容は、常に":safe"とされたものです。 また、Layout用のTemplate(
web/templates/layout/app.html.eex`では、
ここに、Templateが展開されることになります。
<%= render @view_module, @view_template, assigns %>
Error View
Phoenixには、ErrorView(/web/views/error_view.ex
)と呼ばれるViewがあります。このViewの目的は、一般的な二つのエラー、404と500の表示を行うことです。
defmodule HelloPhoenix.ErrorView do
use HelloPhoenix.Web, :view
def render("404.html", _assigns) do
"Page not found"
end
def render("500.html", _assigns) do
"Server internal error"
end
# In case no render clause matches or no
# template is found, let's render it as 500
def template_not_found(_template, assigns) do
render "500.html", assigns
end
end
エラーが発生したとき、開発環境ではいろいろエラー情報が表示されますが、製品環境ではエラー情報を表示しないようにしなければなりません。これを制御するのが、config/dev.exs
にあるdebug_errors: false
です。
use Mix.Config
config :hello_phoenix, HelloPhoenix.Endpoint,
http: [port: 4000],
debug_errors: false,
code_reloader: true,
. . .
エラー表示にTemplateを使う場合は、web/templates/error
ディレクトリを使いますが、デフォルトでは作成されません。必要なら手動で作成します。