From a92b03381d26a47891ea34f94c82fa6415cf245d Mon Sep 17 00:00:00 2001 From: Michael Davis Date: Sun, 2 Dec 2018 21:38:34 -0500 Subject: [PATCH] Sigil L for safe Slime HTML (#63) * Initial ~l and ~L macros * Document * Test * Escape the octothorpe so it's included in the docs * Fix bad test * Interpolation -> Templating in docs and error msg --- lib/phoenix_slime.ex | 40 +++++++++++++++++++++++++++++++++++++ test/phoenix_slime_test.exs | 1 + 2 files changed, 41 insertions(+) diff --git a/lib/phoenix_slime.ex b/lib/phoenix_slime.ex index 04df635..db98131 100644 --- a/lib/phoenix_slime.ex +++ b/lib/phoenix_slime.ex @@ -1,2 +1,42 @@ defmodule PhoenixSlime do + @doc """ + Provides the `~l` sigil with HTML safe Slime syntax inside source files. + + Raises on attempts to use `\#{}`. Use `~L` to allow templating with `\#{}`. + + iex> import PhoenixSlime + iex> assigns = %{w: "world"} + iex> ~l"\"" + ...> p = "hello " <> @w + ...> "\"" + {:safe, [[["" | "

"] | "hello world"] | "

"]} + """ + defmacro sigil_l(expr, opts) do + handle_sigil(expr, opts, __CALLER__.line) + end + + @doc """ + Provides the `~L` sigil with HTML safe Slime syntax inside source files. + + iex> import PhoenixSlime + iex> ~L"\"" + ...> p hello \#{"world"} + ...> "\"" + {:safe, [[["" | "

hello "] | "world" ] | "

"]} + """ + defmacro sigil_L(expr, opts) do + handle_sigil(expr, opts, __CALLER__.line) + end + + defp handle_sigil({:<<>>, _, [expr]}, [], line) do + expr + |> Slime.Renderer.precompile() + |> EEx.compile_string(engine: Phoenix.HTML.Engine, line: line + 1) + end + + defp handle_sigil(_, _, _) do + raise ArgumentError, ~S(Templating is not allowed with #{} in ~l sigil.) <> + ~S( Remove the #{}, use = to insert values, or ) <> + ~S(use ~L to template with #{}.) + end end diff --git a/test/phoenix_slime_test.exs b/test/phoenix_slime_test.exs index acd83b6..8013ad9 100644 --- a/test/phoenix_slime_test.exs +++ b/test/phoenix_slime_test.exs @@ -1,6 +1,7 @@ defmodule PhoenixSlimeTest do use ExUnit.Case alias Phoenix.View + doctest PhoenixSlime defmodule MyApp.PageView do use Phoenix.View, root: "test/fixtures/templates"