feat!: configure runtime attributes function (#202)
This commit is contained in:
parent
8a9e06448b
commit
dc57221bc9
7 changed files with 78 additions and 24 deletions
|
@ -42,13 +42,16 @@ Temple works out of the box without any configuration, but here are a couple of
|
||||||
|
|
||||||
### Engine
|
### 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
|
```elixir
|
||||||
# config/config.exs
|
# config/config.exs
|
||||||
|
|
||||||
config :temple,
|
config :temple,
|
||||||
engine: Phoenix.HTML.Engine
|
engine: EEx.SmartEngine,
|
||||||
|
attributes: {Temple, :attributes}
|
||||||
```
|
```
|
||||||
|
|
||||||
### Aliases
|
### Aliases
|
||||||
|
|
|
@ -96,16 +96,40 @@ defmodule Temple do
|
||||||
require Temple.Renderer
|
require Temple.Renderer
|
||||||
|
|
||||||
Temple.Renderer.compile(unquote(block))
|
Temple.Renderer.compile(unquote(block))
|
||||||
|> then(fn
|
|
||||||
{:safe, template} ->
|
|
||||||
template
|
|
||||||
|
|
||||||
template ->
|
|
||||||
template
|
|
||||||
end)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc false
|
@doc false
|
||||||
defdelegate engine, to: Temple.Renderer
|
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
|
end
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
defmodule Temple.Ast.Utils do
|
defmodule Temple.Ast.Utils do
|
||||||
@moduledoc false
|
@moduledoc false
|
||||||
|
|
||||||
|
@attributes Application.compile_env(
|
||||||
|
:temple,
|
||||||
|
:attributes,
|
||||||
|
{Phoenix.HTML, :attributes_escape}
|
||||||
|
)
|
||||||
|
|
||||||
def snake_to_kebab(stringable),
|
def snake_to_kebab(stringable),
|
||||||
do: stringable |> to_string() |> String.replace_trailing("_", "") |> String.replace("_", "-")
|
do: stringable |> to_string() |> String.replace_trailing("_", "") |> String.replace("_", "-")
|
||||||
|
|
||||||
|
@ -34,7 +40,7 @@ defmodule Temple.Ast.Utils do
|
||||||
[
|
[
|
||||||
{:expr,
|
{:expr,
|
||||||
quote do
|
quote do
|
||||||
Phoenix.HTML.attributes_escape(unquote(List.first(attrs)))
|
unquote(__MODULE__).__attributes__(unquote(List.first(attrs)))
|
||||||
end}
|
end}
|
||||||
]
|
]
|
||||||
end
|
end
|
||||||
|
@ -57,7 +63,7 @@ defmodule Temple.Ast.Utils do
|
||||||
def build_attr("rest!", {_, _, _} = value) do
|
def build_attr("rest!", {_, _, _} = value) do
|
||||||
expr =
|
expr =
|
||||||
quote do
|
quote do
|
||||||
Phoenix.HTML.attributes_escape(unquote(value))
|
unquote(__MODULE__).__attributes__(unquote(value))
|
||||||
end
|
end
|
||||||
|
|
||||||
[{:expr, expr}]
|
[{:expr, expr}]
|
||||||
|
@ -66,7 +72,7 @@ defmodule Temple.Ast.Utils do
|
||||||
def build_attr(name, {_, _, _} = value) do
|
def build_attr(name, {_, _, _} = value) do
|
||||||
expr =
|
expr =
|
||||||
quote do
|
quote do
|
||||||
Phoenix.HTML.attributes_escape([{unquote(name), unquote(value)}])
|
unquote(__MODULE__).__attributes__([{unquote(name), unquote(value)}])
|
||||||
end
|
end
|
||||||
|
|
||||||
[{:expr, expr}]
|
[{:expr, expr}]
|
||||||
|
@ -154,4 +160,10 @@ defmodule Temple.Ast.Utils do
|
||||||
|
|
||||||
ast
|
ast
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def __attributes__(attributes) do
|
||||||
|
{mod, func} = @attributes
|
||||||
|
|
||||||
|
apply(mod, func, [attributes])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -55,7 +55,7 @@ defmodule Temple.Component do
|
||||||
import Temple
|
import Temple
|
||||||
@doc false
|
@doc false
|
||||||
def component(func, assigns, _) do
|
def component(func, assigns, _) do
|
||||||
{:safe, apply(func, [assigns])}
|
apply(func, [assigns])
|
||||||
end
|
end
|
||||||
|
|
||||||
defmacro inner_block(_name, do: do_block) do
|
defmacro inner_block(_name, do: do_block) do
|
||||||
|
|
|
@ -1,13 +1,22 @@
|
||||||
defmodule Temple.Support.Helpers do
|
defmodule Temple.Support.Helpers do
|
||||||
|
import ExUnit.Assertions
|
||||||
|
|
||||||
defmacro assert_html(expected, actual) do
|
defmacro assert_html(expected, actual) do
|
||||||
quote do
|
quote location: :keep do
|
||||||
assert unquote(expected) == Phoenix.HTML.safe_to_string(unquote(actual)), """
|
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 ---
|
||||||
#{unquote(expected)}----------------
|
#{expected}----------------
|
||||||
|
|
||||||
--- Actual ---
|
--- Actual ---
|
||||||
#{Phoenix.HTML.safe_to_string(unquote(actual))}--------------
|
#{actual}--------------
|
||||||
"""
|
"""
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ defmodule Temple.Ast.UtilsTest do
|
||||||
|
|
||||||
assert Macro.to_string(
|
assert Macro.to_string(
|
||||||
quote do
|
quote do
|
||||||
Phoenix.HTML.attributes_escape([{"class", unquote(class_ast)}])
|
Temple.Ast.Utils.__attributes__([{"class", unquote(class_ast)}])
|
||||||
end
|
end
|
||||||
) == Macro.to_string(actual)
|
) == Macro.to_string(actual)
|
||||||
end
|
end
|
||||||
|
@ -74,7 +74,7 @@ defmodule Temple.Ast.UtilsTest do
|
||||||
|
|
||||||
assert Macro.to_string(
|
assert Macro.to_string(
|
||||||
quote do
|
quote do
|
||||||
Phoenix.HTML.attributes_escape(unquote(rest_ast))
|
Temple.Ast.Utils.__attributes__(unquote(rest_ast))
|
||||||
end
|
end
|
||||||
) == Macro.to_string(rest_actual)
|
) == Macro.to_string(rest_actual)
|
||||||
end
|
end
|
||||||
|
|
|
@ -14,7 +14,7 @@ defmodule TempleTest do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|> :erlang.iolist_to_binary()
|
|> Phoenix.HTML.safe_to_string()
|
||||||
|
|
||||||
# heex
|
# heex
|
||||||
expected = """
|
expected = """
|
||||||
|
@ -30,4 +30,10 @@ defmodule TempleTest do
|
||||||
assert expected == result
|
assert expected == result
|
||||||
end
|
end
|
||||||
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
|
end
|
||||||
|
|
Reference in a new issue