如何在Phoenix

时间:2016-05-29 04:19:53

标签: elixir phoenix-framework

在node express中,我可以这样做:

app.get("*", function(req, res) {

    res.redirect("/");

});

我如何在凤凰城做相同的事情?

我根据“编程凤凰”一书中的第一个练习设置了基本路线,控制器,视图和模板。

router.ex

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

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

hello_controller

defmodule Hello.HelloController do
    use Hello.Web, :controller
    def world(conn, _params) do
        render conn, "world.html"
    end
end

hello_view.ex

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

1 个答案:

答案 0 :(得分:2)

我不确定我完全理解这个问题,因为我不熟悉nodejs / express,但我会假设这是发生的事情:

  • 捕获所有路线app.get("*"

  • 将所有路线重定向至"/"

方法1:在调用路由器插件之前使用插头重定向。

注意:此方法相当粗略,将有效地呈现所有其他路线,所有路线都将被重定向到@route,无论如何。我能想到的唯一一个例子就是网页只有一个页面可以呈现。

1.将重定向插头添加到Endpoint模块。该模块有一系列plugs。该文件位于lib/endpoint.ex
defmodule Tester.Endpoint do
  use Phoenix.Endpoint, otp_app: :tester

  socket "/socket", Tester.UserSocket

  plug Plug.Static,
    at: "/", from: :tester, gzip: false,
    only: ~w(css fonts images js favicon.ico robots.txt)

  plug Plug.RequestId
  plug Plug.Logger

  plug Plug.Parsers,
    parsers: [:urlencoded, :multipart, :json],
    pass: ["*/*"],
    json_decoder: Poison

  plug Plug.MethodOverride
  plug Plug.Head

  plug Plug.Session,
    store: :cookie,
    key: "_tester_key",
    signing_salt: "cS+8eqyy"

  plug Tester.Catch  # <-- Add plug module here or plug function.

  plug Tester.Router

end
2.编写插头模块(或首选功能)lib/catch.ex
defmodule Tester.Catch do
  @route "/"
  @redirect_to String.split(@route, "/", [trim: :true])

  def init(opts), do: opts

  def call(conn, opts), do: redirect(conn, opts)

  defp redirect(%{path_info: @redirect_to} = conn, _opts) do
      conn
  end
  defp redirect(%{path_info: _path_info} = conn, _opts) do
      Phoenix.Controller.redirect(conn, to: @route) |> Plug.Conn.halt()
  end

end

方法2:使用凤凰路线重定向以捕获所有其他不匹配的路线。

注意:首选此方法是因为由于模式匹配,只要它们位于顶部,您就可以保留匹配的路由,然后您可以捕获所有路由在router.ex范围的底部。

defmodule Tester.Router do
  use Tester.Web, :router

  pipeline :browser do
    plug :accepts, ["html"]
    plug :fetch_session
    plug :fetch_flash
    plug :protect_from_forgery
    plug :put_secure_browser_headers
  end

  pipeline :api do
    plug :accepts, ["json"]
  end

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

    get "/", PageController, :index
    get "/page", PageController, :index
    get "/page/test", PageController, :other

    get "/*path", RedirectController, :redirector
  end

end


defmodule Tester.RedirectController do
  use Tester.Web, :controller
  @send_to "/"

  def redirector(conn, _params), do: redirect(conn, to: @send_to)

end

请参阅: