/var/log/messages

Apr 13, 2019 - 3 minute read - Comments - programming

phoenix excersize (8)

挙動不審の件、色々とボケ倒していたようです。結論? から言うと plug は

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

アクションを呼び出す前に conn を transform、という事でした。また、

  plug :assign_welcome_message, "Welcome Back"

  defp assign_welcome_message(conn, msg) do
    assign(conn, :message, msg)
  end

という定義より view には message という変数を表示する形の記述にしておく必要が (勿論) ありました。

<div class="jumbotron">
  <h2> <%= @message %></h2>
</div>

show アクションでも表示させるためには

  • show.html.eex に message という変数を表示
  • plug の when が指定されている場合は表示させるアクションを明示

しなければならないです。

そして

もりリキがあれば、続きの確認な記録を以降に列挙の方向です。

Sending responses directly

  • ステイタスのみで本文が無い応答は send_resp/3 を使う
  • content_type を明示する場合、put_resp_content_type/2 を使う
  • 以下が例示
def index(conn, _params) do
  conn
  |> put_resp_content_type("text/plain")
  |> send_resp(201, "")
end

Assigning Layouts

  • レイアウトはテンプレートの特別なサブセットで web/templates/layout 配下に置かれる
  • ここに app.html.eex を Phoenix が自動生成
  • レイアウトは単なるテンプレートなのでそれをレンダリングするための view が必要
  • 確かに views 配下に hello_view.ex、layout_view.ex、page_view.ex が存在しています
  • レイアウトなしでテンプレートをレンダリングする方法
def index(conn, _params) do
  conn
  |> put_layout(false)
  |> render("index.html")
end
  • パイプラインな関数呼び出しにおいては引数を括弧で囲む必要がある
  • 以下なスタックトレイスが表示されたら上の不具合の可能性が大きい
**(FunctionClauseError) no function clause matching in Plug.Conn.get_resp_header/2

Stacktrace

    (plug) lib/plug/conn.ex:353: Plug.Conn.get_resp_header(false, "content-type")

以下がその不具合な実装の例。

def index(conn, _params) do
  conn
  |> put_layout false
  |> render "index.html"
end
  • 異なるレイアウトを適用する例
  • app.html.eex を admin.html.eex としてコピィし、中身を編集 (ロゴ表示の行を削除)
  • page_controller.ex の index アクションを以下に修正
def index(conn, _params) do
  conn
  |> put_layout("admin.html")
  |> render("index.html")
end

Overridig Rendering Formats

  • レンダリング形式をその場で変更する必要がある場合、どうするか
  • プレーンテキスト、あるいは JSON の場合、など
  • _format というクエリパラメータでフォーマット変更が可能
  • PageController の index アクションの例
    • PageView という view
    • web/templates/page というテンプレートディレクトリ
    • index.html.eex というテンプレート
  • テキストをレンダリングするための代替テンプレートがない
  • web/templates/page/index.text.eex を追加すれば良い
  • テキストフォーマットを受け入れるべき、ということを Router に伝える必要がある
  • 以下のように実装を修正
defmodule HelloWeb.Router do
  use HelloWeb, :router

  pipeline :browser do
    plug :accepts, ["html", "text"]
    plug :fetch_session
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end
  • あるいはアクションの定義にて “index.html” を render するのではなく、以下のような記述にする必要があるとのこと
def index(conn, _params) do
  render(conn, :index)
end
  • これで http://localhost:8080/?_format=text にアクセスすると index.text.eex なナニが表示されるはず

Setting the HTTP Status

  • 404 ページのレンダリングの正しい方法について
def index(conn, _params) do
  conn
  |> put_status(:not_found)
  |> put_view(HelloWeb.ErrorView)
  |> render("404.html")
end

続きは

Redirection の項から。

re:Work 大人のための囲碁入門が昨日到着

comments powered by Disqus