【问题标题】:Elixir Phoenix global variable plugElixir Phoenix 全局变量插件
【发布时间】:2015-11-23 08:35:47
【问题描述】:

我正在尝试根据其域获取网站的标识符,但在为其编写插件后,我遇到了一个问题,系统中的所有链接都返回根 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”条件。

【问题讨论】:

    标签: elixir phoenix-framework


    【解决方案1】:

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

    来自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 帮助器通常在需要域时使用(例如电子邮件)。

    【讨论】:

    • 感谢 Gazler。你能告诉我应该把这个 struct_url 覆盖的代码放在哪里,以便它在全球范围内有效吗?对不起,我是凤凰城的新手。
    • @PratikKhadloya 首先,你肯定需要使用_url 格式而不是_path 格式吗?如果你这样做了,你能告诉我你从哪里打电话吗?
    • 我的一个链接是登录链接,我不知道如何使用 _url。 <%= link "Login", to: "/login", class: "nav-link" %>。当我单击此链接时,它会再次返回主页的整个 html,给人一种页面中没有发生任何事情的感觉。我还没有尝试过 struct_url 解决方案。
    • @PratikKhadloya 您的登录链接不是要链接到当前网址吗?例如使用login_path(@conn, :index) 将链接到/loginlogin_url(@conn, :index) 将链接到http://example.com/login
    • 感谢@Gazler 使用_url 路径设置struct_url 确实可以将其链接到ll.com:4000/register,但它仍然加载主页而不是注册页面:(
    【解决方案2】:

    您的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

    【讨论】:

    • 谢谢!我修复了 if 条件,但这并没有解决问题:(。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-14
    • 2017-03-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多