How can I check if a layout file exists in the layouts folder?

phoenix
layout

#1

I have a very simple plug that sets the subdomain layout based on the Endpoint subdomain.

defmodule MyApp.Plug.Subdomain do
  import Plug.Conn
  alias MyApp.Endpoint

  def init(opts), do: opts

  def call(conn, _) do
    subdomain = get_subdomain(conn.host)

    # Check here, does this #{subdomain}.eex layout file exist?

    conn
    |> assign(:subdomain_layout, subdomain)
  end

  @spec get_subdomain(String.t()) :: String.t()
  defp get_subdomain(host) do
    String.replace(host, ~r/.?#{Endpoint.host()}/, "")
  end
end

How can I check if the layout file exists in the folder? Can I use File.exists??


#2

Forgot to mention, this is what I’ve tried but it doesn’t seem to detect the file.

# Running code is in /Users/sergiotapia/Work/myapp/lib/myapp/plug/subdomain.ex
File.exists?("../../myapp_web/templates/layouts/#{subdomain}.eex") |> IO.inspect()
# false

#3

It wouldn’t work if you use releases and don’t copy source files, probably.

As far as I understand, each phoenix layout template is turned into a render clause in your MyAppWeb.LayoutView like render("app.html", assigns), so maybe you can try using that somehow. That is, the information about which layouts are available is there, but it might be tricky to get it.

Or write a helper function which would contain the information of the existing layouts if the above doesn’t work out:

defmodule Layouts do

  @spec exists?(String.t()) :: boolean
  def exists?(template)

  "../../myapp_web/templates/layouts"
  |> File.ls!()
  |> Enum.map(fn template ->
    template = String.replace(template, ".exs", "")
    def exists?(unquote(template)), do: true
  end)

  def exists?(_unmatched), do: false
end