diff --git a/lib/dsl/engine.ex b/lib/dsl/engine.ex new file mode 100644 index 0000000..6358b0f --- /dev/null +++ b/lib/dsl/engine.ex @@ -0,0 +1,42 @@ +defmodule Dsl.Engine do + @behaviour Phoenix.Template.Engine + + def compile(path, _name) do + template = + path + |> File.read!() + |> Code.string_to_quoted!(file: path) + |> handle_assigns() + + quote do + use Dsl + + htm(do: unquote(template)) + end + end + + defp handle_assigns(quoted) do + quoted + |> Macro.prewalk(fn + {:@, _, [{key, _, _}]} -> + quote do + case Access.fetch(var!(assigns), unquote(key)) do + {:ok, val} -> + val + + :error -> + raise ArgumentError, """ + assign @#{unquote(key)} not available in Dsl template. + Please make sure all proper assigns have been set. If this + is a child template, ensure assigns are given explicitly by + the parent template as they are not automatically forwarded. + Available assigns: #{inspect(Enum.map(var!(assigns), &elem(&1, 0)))} + """ + end + end + + ast -> + ast + end) + end +end diff --git a/mix.exs b/mix.exs index 98beb06..b04aa8e 100644 --- a/mix.exs +++ b/mix.exs @@ -26,7 +26,9 @@ defmodule Dsl.MixProject do # Run "mix help deps" to learn about dependencies. defp deps do [ - {:phoenix_html, "~> 2.13"} + {:phoenix_html, "~> 2.13"}, + {:phoenix, "~> 1.4", optional: true}, + {:dialyxir, "~> 1.0.0-rc.6", only: [:dev], runtime: false} ] end end diff --git a/mix.lock b/mix.lock index 49b5207..d9725e0 100644 --- a/mix.lock +++ b/mix.lock @@ -1,6 +1,10 @@ %{ + "dialyxir": {:hex, :dialyxir, "1.0.0-rc.6", "78e97d9c0ff1b5521dd68041193891aebebce52fc3b93463c0a6806874557d7d", [:mix], [{:erlex, "~> 0.2.1", [hex: :erlex, repo: "hexpm", optional: false]}], "hexpm"}, + "erlex": {:hex, :erlex, "0.2.1", "cee02918660807cbba9a7229cae9b42d1c6143b768c781fa6cee1eaf03ad860b", [:mix], [], "hexpm"}, "mime": {:hex, :mime, "1.3.1", "30ce04ab3175b6ad0bdce0035cba77bba68b813d523d1aac73d9781b4d193cf8", [:mix], [], "hexpm"}, + "phoenix": {:hex, :phoenix, "1.4.3", "8eed4a64ff1e12372cd634724bddd69185938f52c18e1396ebac76375d85677d", [:mix], [{:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:phoenix_pubsub, "~> 1.1", [hex: :phoenix_pubsub, repo: "hexpm", optional: false]}, {:plug, "~> 1.7", [hex: :plug, repo: "hexpm", optional: false]}, {:plug_cowboy, "~> 1.0 or ~> 2.0", [hex: :plug_cowboy, repo: "hexpm", optional: true]}], "hexpm"}, "phoenix_html": {:hex, :phoenix_html, "2.13.2", "f5d27c9b10ce881a60177d2b5227314fc60881e6b66b41dfe3349db6ed06cf57", [:mix], [{:plug, "~> 1.5", [hex: :plug, repo: "hexpm", optional: false]}], "hexpm"}, + "phoenix_pubsub": {:hex, :phoenix_pubsub, "1.1.2", "496c303bdf1b2e98a9d26e89af5bba3ab487ba3a3735f74bf1f4064d2a845a3e", [:mix], [], "hexpm"}, "plug": {:hex, :plug, "1.8.0", "9d2685cb007fe5e28ed9ac27af2815bc262b7817a00929ac10f56f169f43b977", [:mix], [{:mime, "~> 1.0", [hex: :mime, repo: "hexpm", optional: false]}, {:plug_crypto, "~> 1.0", [hex: :plug_crypto, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: true]}], "hexpm"}, "plug_crypto": {:hex, :plug_crypto, "1.0.0", "18e49317d3fa343f24620ed22795ec29d4a5e602d52d1513ccea0b07d8ea7d4d", [:mix], [], "hexpm"}, }