スポンサーリンク

2015年6月2日

Phoenixのコントローラ(Controllers)について分かったこと(その2)

タイトル: Phoenixのコントローラ(Controllers)について分かったこと(その2)


目的: Phoenixアプリケーションのコントローラ(Controllers)について分かったことを記述する。


実施環境:

OS: Windows8.1
Erlang: Eshell V6.4
Elixir: v1.0.4
Phoenix Framework: v0.13.1
Node.js: v0.12.4

目次:


  1. 概要
  2. Assigning Layoutsの使い方
  3. Overriding Rendering Formatsの使い方
  4. Setting the Content Typeの使い方(未完成)
  5. Setting the HTTP Statusの使い方
  6. Redirectionの使い方

1.概要


1.1

注意!!
この記事は、Phoenix - Guides ControllersをGoogle翻訳を使い、分かったことを書いています。
原文を丸々翻訳しているわけではないので、
流れや説明がおかしいところ多々ありますが、その点注意して下さい。

英語が分かる方は、公式ガイドを見た方が確実です。

また、管理人の英語力は本人がドン引きするほど低いので、
間違った解釈及び理解している部分が多分にあると思います。

それでも構わないという方は見て頂けたら嬉しいです。

また、ご指摘等があれば受け付けておりますゆえ、遠慮なくお願いします。
特に間違えて習得している部分は教えて頂ければ、本当に助かります。

1.2

あらかじめ、テスト用のプロジェクトは作成しておいて下さい。
参考: Phoenixが欲しいって言うからNode.jsをインスコするよ!!

もしくは、その1を実施して下さい。
参考: Phoenixのコントローラ(Controllers)について分かったこと(その1)

※ その1は実施していなくても、その2の実施に問題はありません。

2.Assigning Layoutsの使い方


2.1

Phoenixが生成した、レイアウトのテンプレート。
全てのテンプレートがデフォルトでレンダリングされるレイアウト。
/web/templates/layout/application.html.eex

レイアウトはただのテンプレートなので、
レンダリングしてくれるビューを必要とする。

上記のテンプレートに対応しているのは、
/web/views/layout_view.exで定義されているLayoutViewモジュール。

2.2

レイアウトを切り替えるためには、
Phoenix.Controllerモジュールのput_layout機能を使用する。

第一引数は、レイアウトのベース名を文字列を取る。
第二引数は、booleanを取る。

例のソースコードだと、
第一引数を取ってなかったり、
trueとfalseで何が変わるのとか、
書いてないから引数よく分からない。

2.3

何れにせよ、実際に使ってみよう。

/web/controllers/page_controller.exを開き、
indexアクションを以下のように修正する。
----
def index(conn, params) do
  conn
  |> put_layout(false)
  |> render "index.html"
end
----

実行したけど、表示がいきなりしょぼくなったな・・・

なんか、重要!!とかって書かれてる部分がある。
put_layout使う時は、()で引数囲うこと・・・とか。
つまり、"put_layout false"と言った記述はダメらしい。

2.4

続き、行きましょう・・・

/web/templates/layoutディレクトリに以下の名称のファイルを作成する。
内容は、同ディレクトリのapplication.html.eexをコピーするので、
ファイル自体をコピーしてリネームでもいいですね。

作成ファイル: admin.html.eex

んで、作成したファイルから以下の行を削除する。
<span class="logo"></span>

2.5

/web/controllers/page_controller.exのindexアクションで
先ほど作成したファイルを指定してみる。
----
def index(conn, params) do
  conn
  |> put_layout("admin.html")
  |> render "index.html"
end
----

実行すると、ロゴなしの画面が出てきましたね。

3.Overriding Rendering Formatsの使い方


3.1

あらかじめ、書いておきます。
この項目はよく分からなかった。
一応実行できたので、何となくは分かるのですが、割かし曖昧です。
そのことを念頭に置いて読んで下さい。(飛ばしても結構です)

レンダリングしたい対象がテキストやJSON、HTMLである時の方法について書いてあるっぽい。

んで、この機能は・・・
フォーマットクエリ文字列パラメータを使用してその場でフォーマットを変更できる。
また、使用するには・・・
適切な名前のビューと適切なディレクトリに適切な名前のテンプレートが必要とのこと。

3.2

実際にやってみる。

/web/templates/pageディレクトリへ新規にファイルを作成する。
作成ファイル: index.text.eex

内容は以下の一文(普通にテキストファイルですね)
"OMG, this is actually some text."

3.3

/web/router.exを開き、
pipeline :browserを以下のように修正する。
----
pipeline :browser do
  plug :accepts, ["html", "text"]
  plug :fetch_session
  plug :fetch_flash
  plug :protect_from_forgery
end
----

ここで扱えるフォーマット?を追加している。
修正前: plug :accepts, ["html"]
修正後: plug :accepts, ["html", "text"]

テキストが増えてますね。

3.4

/web/controllers/page_controller.exを開き、
indexアクションを以下のように修正する。
----
def index(conn, _params) do
  render conn, :index
end
----

では実行して表示を確認する。
この段階では、画面内容は変わっていませんね。

"render conn, :index"にご注目。
"index.html"が:indexになっていますね。

これは、:indexで指定していると、自動でindex.html.eesがレンダリングされているみたいですね。
ここ、原文読んでもよく分からなかったのです。

3.5

次は、テンプレートにテキストファイルを指定します。
テキストのテンプレートでもデータを渡すことができることをやるみたいですね。

再び、indexアクションを以下のように修正して下さい。
----
def index(conn, params) do
  render conn, "index.text", message: params["message"]
end
----

テキストファイルを指定してますね。また、messageで値を渡してますね。

ところで、気付いた方いますでしょうかparamsに_がありません。
_なしでparamsの使用がないと警告が出ます。だから、使わない時は_を付けるみたいですね。
例)
web/controllers/page_controller.ex:6: warning: variable params is unused

3.6

次に、
/web/templates/page/index.text.eexを開き、以下のように修正する。

"OMG, this is actually some text." <%= @message %>

3.7

ここまで来たら、実行して下さい。
以下のアドレスにアクセスして下さい。
アドレス: http://localhost:4000/?format=text&message=CrazyTown

フォーマットの指定とmessageの値をURLの中に入れてます。

4.Setting the Content Typeの使い方(未完成)


4.1

HTTPを変更することにより、必要なフォーマットの任意の並べ替えをレンダリングできるらしい・・・
また、ヘッダーを受け入れ、適切なテンプレートを提供する必要があるっと・・・
よく分かりませんねw

物は試しと言うことで実行しましょう。
indexアクションでXMLをレンダリングしたい場合。

すいません、エラーが出て直せません・・・
その内分かったら記述します。

有効なコンテンツのMIMEタイプは別のドキュメントを参照すること
参考: https://github.com/elixir-lang/plug/blob/master/lib/plug/mime.types

思いました・・・Overriding Rendering Formatsでできないんでしょうか?
まぁ、いずれ検証するとして今は項目を消化してしまいましょう。

5.Setting the HTTP Statusの使い方


5.1

何か前に似たようなのやりましたね。send_respでしたっけ?
関数名が違うのでまた違うのでしょうが・・・

応答のHTTPステータスコードを設定する方法。
Plug.Connモジュールをインポートして、put_status関数を使用する。

参考: https://github.com/elixir-lang/plug/blob/master/lib/plug/conn/status.ex#L7-L63

5.2

使ってみよう。

/web/controllers/page_controller.exを開き、
indexアクションを以下のように修正する。
----
def index(conn, _params) do
  conn
  |> put_status(202)
  |> render "index.html"
end
----

実行して、HTTPステータスを確認する。

5.3

次、以下のように修正する。
----
def index(conn, _params) do
  conn
  |> put_status(:not_found)
  |> render "index.html"
end
----

実行して、HTTPステータスを確認する。
HTTPステータスは404not_foundなのに、ページはindex.htmlですね。

5.4

なので、エラーページを出すために以下のように修正する。
----
def index(conn, _params) do
  conn
  |> put_status(:not_found)
  |> render(HelloPhoenix.ErrorView, "404.html")
end
----

実行する。
Phoenixのロゴの下に"Page not found"と表示されましたね。

つまり、HTTPステータスは送れるけど、実際のレンダリングには関係ないよってことらしい。
レンダリングの切り替えは行う必要があるってことですね。

しかし、PageControllerの適切なビューはPageViewのはずなのに、
ErrorViewが出てくるってどうなっているんでしょうか?
疑問点ですね・・・

6.Redirectionの使い方


6.1

あえて、書きます。
リダイレクトのさせ方ですね。

リダイレクト関数があるみたいですね。
アプリケーション内のパスへのリダイレクトと
URLにリダイレクトするのは区別するようです。

6.2

/web/router.exを開き、新しくscope(ルート)を追加する。
----
scope "/", HelloPhoenix do
  get "/redirect_test", PageController, :redirect_test, as: :redirect_test
end
----

6.3

"mix phoenix.routes"コマンドを使い、ルーティングを見てみます。
以下が追加されていますね。

redirect_test_path  GET  /redirect_test     HelloPhoenix.PageController.redirect_test/2

6.4

/web/controllers/page_controller.exを開き、
indexアクションを以下のように修正する。
アプリケーション内のパスを指定してリダイレクトするやり方です。

def index(conn, _params) do
  redirect conn, to: "/redirect_test"
end

また、redirect_testアクションを新しく追加する。
def redirect_test(conn, _params) do
  text conn, "Redirect!"
end

実行します。"localhost:4000"にアクセスして下さい。
Redirect!と表示されますね。

まず、indexアクションが実行され、/redirect_testのパスへリダイレクトしてます。
その後、redirect_testアクションが実行され、textで出力しています。

開発者ツールを使ってHTTPステータスを確認してみると実際に動きが見れます。

6.5

今度は、indexアクションを以下のように修正して下さい。
URLを指定してリダイレクトさせるやり方です。
----
def index(conn, _params) do
  redirect conn, external: "http://elixir-lang.org/"
end
----

はい、実行。
Elixirのサイトへリダイレクトしましたね。

6.6

続いてPathHelpersを使ったやり方です。
----
defmodule HelloPhoenix.PageController do
  use HelloPhoenix.Web, :controller

  def index(conn, _params) do
    redirect conn, to: redirect_test_path(conn, :redirect_test)
  end
end
----

実行。
再び、Redirect!と表示されますね。

6.7

最後です。
URLをPathHelpersで指定する。
----
def index(conn, _params) do
  redirect conn, external: redirect_test_url(conn, :redirect_test)
end
----

ry
Redirect!と表示されます。

URLの指定は必ずしも外部でなくて構わないみたいです。
ちなみに、external:をto:に変更すると失敗します。

以上!!

以下、参考とさせて頂いたサイト様

管理人の独り言~
長々とその1からお疲れ様でした。
目を通して頂いた方はありがとうございます。

まだ、分かってないことはありますが・・・
まぁ、追々と言うことで・・・
また分かったら追記もしくは記事を書きますので・・・

人気の投稿