Elixir Phoenix 全局变量插件

Elixir Phoenix global variable plug

我试图根据网站的域获取网站的标识符,但在为其编写插件后,我 运行 遇到了一个问题,其中系统中的所有链接都返回根 url 内容.

lib/myapp/plugs/request_var.ex

defmodule Myapp.Plug.RequestVar do
  import Plug.Conn

  @doc false
  def init(default), do: default

  @doc false
  def call(conn, router) do
    host = conn.host
    if host == "ll.com" || host == "domain1.com" do
      slug = "domain1"
    else
      slug = "domain2"
    end

    conn |> put_private(:site_slug, slug)
  end
end

在lib/myapp/endpoint.ex

plug Myapp.Plug.RequestVar, Myapp.Router
plug Myapp.Router

这个插头有什么问题吗?

编辑: 根据回复修复了 "if" 条件。

您的 if 子句有误。它将永远是 true.

iex(1)> host = "l2.com"
"l2.com"
iex(2)> host == "ll.com" || "domain1.com"
"domain1.com"

对于有效域和无效域。

iex(3)> host = "ll.com"                  
"ll.com"
iex(4)> host == "ll.com" || "domain1.com"
true

测试:

iex(6)> if host == "ll.com" || "domain1.com" do
...(6)>   IO.puts "if"
...(6)> end
if
:ok

您必须将子句更改为 if host == "ll.com" || host == "domain1.com" do。但。使用这种从句不是惯用的。一般用pattern-matching.

比较好

url 是从您的 endpoint.url 生成的,而不是 Plug.Conn

host

来自https://github.com/phoenixframework/phoenix/blob/8fe0538fd7be2adb05e2362b02fa8bd6bf3c6c46/lib/phoenix/router/helpers.ex#L13

  def url(_router, %Conn{private: private}) do
    private.phoenix_endpoint.url
  end

  def url(_router, %Socket{endpoint: endpoint}) do
    endpoint.url
  end

  def url(_router, %URI{} = uri) do
    uri_to_string(uri)
  end

  def url(_router, endpoint) when is_atom(endpoint) do
    endpoint.url
  end

您可以使用 struct_url/0:

覆盖它
struct_url = update_in(Endpoint.struct_url.host, fn (_) -> "domain2" end)
some_url(struct_url, :index)

您还可以为第二个域定义第二个终结点。如果您的链接是内部链接,那么您应该考虑使用 _path 函数而不是 _url 函数。 _url 助手通常在需要域(例如电子邮件)时使用。