feat!: configure runtime attributes function (#202)

This commit is contained in:
Mitchell Hanberg 2023-06-12 23:38:16 -04:00 committed by GitHub
parent 8a9e06448b
commit dc57221bc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 78 additions and 24 deletions

View File

@ -42,13 +42,16 @@ Temple works out of the box without any configuration, but here are a couple of
### Engine
By default, Temple uses the built in `EEx.SmartEngine`. If you want to use a different engine, this is as easy as setting the `:engine` configuration option.
By default, Temple uses the built in `Phoenix.HTML.Engine`. If you want to use a different engine, this is as easy as setting the `:engine` configuration option.
You can also configure the function that is used for runtime attributes. By default, Temple uses `Phoenix.HTML.attributes_escape/1`.
```elixir
# config/config.exs
config :temple,
engine: Phoenix.HTML.Engine
engine: EEx.SmartEngine,
attributes: {Temple, :attributes}
```
### Aliases

View File

@ -96,16 +96,40 @@ defmodule Temple do
require Temple.Renderer
Temple.Renderer.compile(unquote(block))
|> then(fn
{:safe, template} ->
template
template ->
template
end)
end
end
@doc false
defdelegate engine, to: Temple.Renderer
@doc """
Compiles runtime attributes.
To use this function, you set it in application config.
By default, Temple uses `{Phoenix.HTML, :attributes_escape}`. This is useful if you want to use `EEx.SmartEngine`.
```elixir
config :temple,
engine: EEx.SmartEngine,
attributes: {Temple, :attributes}
```
> #### Note {: .info}
>
> This function does not do any HTML escaping
> #### Note {: .info}
>
> This function is used by the compiler and shouldn't need to be used directly.
"""
def attributes(attributes) do
for {key, value} <- attributes, into: "" do
case value do
true -> ~s| #{key}|
false -> ""
value -> ~s| #{key}="#{value}"|
end
end
end
end

View File

@ -1,6 +1,12 @@
defmodule Temple.Ast.Utils do
@moduledoc false
@attributes Application.compile_env(
:temple,
:attributes,
{Phoenix.HTML, :attributes_escape}
)
def snake_to_kebab(stringable),
do: stringable |> to_string() |> String.replace_trailing("_", "") |> String.replace("_", "-")
@ -34,7 +40,7 @@ defmodule Temple.Ast.Utils do
[
{:expr,
quote do
Phoenix.HTML.attributes_escape(unquote(List.first(attrs)))
unquote(__MODULE__).__attributes__(unquote(List.first(attrs)))
end}
]
end
@ -57,7 +63,7 @@ defmodule Temple.Ast.Utils do
def build_attr("rest!", {_, _, _} = value) do
expr =
quote do
Phoenix.HTML.attributes_escape(unquote(value))
unquote(__MODULE__).__attributes__(unquote(value))
end
[{:expr, expr}]
@ -66,7 +72,7 @@ defmodule Temple.Ast.Utils do
def build_attr(name, {_, _, _} = value) do
expr =
quote do
Phoenix.HTML.attributes_escape([{unquote(name), unquote(value)}])
unquote(__MODULE__).__attributes__([{unquote(name), unquote(value)}])
end
[{:expr, expr}]
@ -154,4 +160,10 @@ defmodule Temple.Ast.Utils do
ast
end
def __attributes__(attributes) do
{mod, func} = @attributes
apply(mod, func, [attributes])
end
end

View File

@ -55,7 +55,7 @@ defmodule Temple.Component do
import Temple
@doc false
def component(func, assigns, _) do
{:safe, apply(func, [assigns])}
apply(func, [assigns])
end
defmacro inner_block(_name, do: do_block) do

View File

@ -1,13 +1,22 @@
defmodule Temple.Support.Helpers do
defmacro assert_html(expected, actual) do
quote do
assert unquote(expected) == Phoenix.HTML.safe_to_string(unquote(actual)), """
--- Expected ---
#{unquote(expected)}----------------
import ExUnit.Assertions
--- Actual ---
#{Phoenix.HTML.safe_to_string(unquote(actual))}--------------
"""
defmacro assert_html(expected, actual) do
quote location: :keep do
unquote(__MODULE__).__assert_html__(unquote_splicing([expected, actual]))
end
end
def __assert_html__(expected, actual) do
actual = actual |> Phoenix.HTML.Engine.encode_to_iodata!() |> IO.iodata_to_binary()
assert expected == actual,
"""
--- Expected ---
#{expected}----------------
--- Actual ---
#{actual}--------------
"""
end
end

View File

@ -25,7 +25,7 @@ defmodule Temple.Ast.UtilsTest do
assert Macro.to_string(
quote do
Phoenix.HTML.attributes_escape([{"class", unquote(class_ast)}])
Temple.Ast.Utils.__attributes__([{"class", unquote(class_ast)}])
end
) == Macro.to_string(actual)
end
@ -74,7 +74,7 @@ defmodule Temple.Ast.UtilsTest do
assert Macro.to_string(
quote do
Phoenix.HTML.attributes_escape(unquote(rest_ast))
Temple.Ast.Utils.__attributes__(unquote(rest_ast))
end
) == Macro.to_string(rest_actual)
end

View File

@ -14,7 +14,7 @@ defmodule TempleTest do
end
end
end
|> :erlang.iolist_to_binary()
|> Phoenix.HTML.safe_to_string()
# heex
expected = """
@ -30,4 +30,10 @@ defmodule TempleTest do
assert expected == result
end
end
describe "attributes/1" do
test "compiles runtime attributes" do
assert ~s| disabled class="foo"| == attributes(disabled: true, checked: false, class: "foo")
end
end
end