diff --git a/CHANGELOG.md b/CHANGELOG.md index 882f037..07c85b3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,9 @@ ## Main -Nothing yet +### Enhancements + +- [breaking] Attributes who values are boolean expressions will be emitted as boolean attributes. ## 0.6.2 diff --git a/README.md b/README.md index c59c1f8..8d61ee4 100644 --- a/README.md +++ b/README.md @@ -22,15 +22,6 @@ def deps do ] end ``` - -or - -```elixir -def deps do - [{:temple, github: "mhanberg/temple"}] -end -``` - ## Goals Currently Temple has the following things on which it won't compromise. @@ -140,7 +131,8 @@ config :phoenix, :template_engines, # you can enable Elixir syntax highlighting in your editor lexs: Temple.LiveViewEngine -# If you're going to be using live_view, make sure to set the `:mode` +# If you're going to be using live_view, make sure to set the `:mode` to `:live_view`. +# This is necessary for Temple to emit markup that is compatible. config :temple, :mode, :live_view # defaults to normal # config/dev.exs @@ -156,6 +148,7 @@ config :your_app, YourAppWeb.Endpoint, ```elixir # app.html.exs +"" html lang: "en" do head do meta charset: "utf-8" @@ -163,7 +156,7 @@ html lang: "en" do meta name: "viewport", content: "width=device-width, initial-scale=1.0" title do: "YourApp ยท Phoenix Framework" - link rel: "stylesheet", href: Routes.static_path(@conn, "/css/app.css") + _link rel: "stylesheet", href: Routes.static_path(@conn, "/css/app.css") end body do diff --git a/integration_test/temple_demo/lib/temple_demo_web/templates/post/form.html.exs b/integration_test/temple_demo/lib/temple_demo_web/templates/post/form.html.exs index 190875c..aaad6e6 100644 --- a/integration_test/temple_demo/lib/temple_demo_web/templates/post/form.html.exs +++ b/integration_test/temple_demo/lib/temple_demo_web/templates/post/form.html.exs @@ -22,6 +22,8 @@ c Form, changeset: @changeset, action: @action do text_input f, :author error_tag(f, :author) + input type: "text", disabled: true, id: "disabled-input" + div do submit "Save" end diff --git a/integration_test/temple_demo/test/temple_demo_web/features/temple_feature_test.exs b/integration_test/temple_demo/test/temple_demo_web/features/temple_feature_test.exs index 67be2dc..2a42384 100644 --- a/integration_test/temple_demo/test/temple_demo_web/features/temple_feature_test.exs +++ b/integration_test/temple_demo/test/temple_demo_web/features/temple_feature_test.exs @@ -37,6 +37,7 @@ defmodule TempleDemoWeb.TempleFeatureTest do s |> click(Query.option("21")) end) |> fill_in(Query.text_field("Author"), with: "Mitchelob Ultra") + |> assert_has(Query.css("#disabled-input[disabled]")) |> click(Query.button("Save")) |> assert_text("Post created successfully.") end diff --git a/lib/temple.ex b/lib/temple.ex index 8b6d5dc..aaff4ea 100644 --- a/lib/temple.ex +++ b/lib/temple.ex @@ -19,6 +19,14 @@ defmodule Temple do id end + # Attributes that result in boolean values will be emitted as a boolean attribute. Examples of boolean attributes are `disabled` and `checked`. + + input type: "text", disabled: true + # + + input type: "text", disabled: false + # + # if and unless expressions can be used to conditionally render content if 5 > 0 do p do @@ -61,7 +69,9 @@ defmodule Temple do There are two "modes", `:normal` (the default) and `:live_view`. - In `:live_view` mode, Temple emits markup that uses functions provided by Phoenix LiveView in order to be fully "diff trackable". + In `:live_view` mode, Temple emits markup that uses functions provided by Phoenix LiveView in order to be fully "diff trackable". These LiveView functions have not been released yet, so if you are going to combine Temple with LiveView, you need to use the latest unreleased default branch from GitHub. + + You should use `:live_view` mode even if you only have a single LiveView. ```elixir config :temple, :mode, :normal # default diff --git a/lib/temple/parser/utils.ex b/lib/temple/parser/utils.ex index 134fc61..cbe2f49 100644 --- a/lib/temple/parser/utils.ex +++ b/lib/temple/parser/utils.ex @@ -18,11 +18,11 @@ defmodule Temple.Parser.Utils do for {name, value} <- attrs, into: "" do name = snake_to_kebab(name) - case value do - {_, _, _} = macro -> - " " <> name <> "=\"<%= " <> Macro.to_string(macro) <> " %>\"" + cond do + (not is_binary(value) && Macro.quoted_literal?(value)) || match?({_, _, _}, value) -> + ~s|<%= {:safe, Temple.Parser.Utils.build_attr("#{name}", #{Macro.to_string(value)})} %>| - value -> + true -> " " <> name <> "=\"" <> to_string(value) <> "\"" end end @@ -37,10 +37,22 @@ defmodule Temple.Parser.Utils do for {name, value} <- attrs, name not in [:inner_block, :inner_content], into: "" do name = snake_to_kebab(name) - " " <> name <> "=\"" <> to_string(value) <> "\"" + build_attr(name, value) end} end + def build_attr(name, true) do + " " <> name + end + + def build_attr(_name, false) do + "" + end + + def build_attr(name, value) do + " " <> name <> "=\"" <> to_string(value) <> "\"" + end + def split_args(not_what_i_want) when is_nil(not_what_i_want) or is_atom(not_what_i_want), do: {[], []} diff --git a/test/parser/nonvoid_elements_aliases_test.exs b/test/parser/nonvoid_elements_aliases_test.exs index f713d44..da0f236 100644 --- a/test/parser/nonvoid_elements_aliases_test.exs +++ b/test/parser/nonvoid_elements_aliases_test.exs @@ -96,7 +96,7 @@ defmodule Temple.Parser.NonvoidElementsAliasesTest do |> Temple.Generator.to_eex() assert result |> :erlang.iolist_to_binary() == - ~s|
\n\n
| + ~s|
>\n\n
| end end end diff --git a/test/parser/temple_namespace_nonvoid_test.exs b/test/parser/temple_namespace_nonvoid_test.exs index 4602654..de508ae 100644 --- a/test/parser/temple_namespace_nonvoid_test.exs +++ b/test/parser/temple_namespace_nonvoid_test.exs @@ -67,7 +67,7 @@ defmodule Temple.Parser.TempleNamespaceNonvoidTest do |> Temple.Generator.to_eex() assert result |> :erlang.iolist_to_binary() == - ~s|
\nfoo\n\n
| + ~s|
>\nfoo\n\n
| end end end diff --git a/test/parser/utils_test.exs b/test/parser/utils_test.exs index afbc348..1c0a844 100644 --- a/test/parser/utils_test.exs +++ b/test/parser/utils_test.exs @@ -8,17 +8,19 @@ defmodule Temple.Parser.UtilsTest do attrs_map = %{ class: "text-red", id: "form1", + disabled: false, inner_block: %{} } attrs_kw = [ class: "text-red", id: "form1", + disabled: true, inner_block: %{} ] assert {:safe, ~s| class="text-red" id="form1"|} == Utils.runtime_attrs(attrs_map) - assert {:safe, ~s| class="text-red" id="form1"|} == Utils.runtime_attrs(attrs_kw) + assert {:safe, ~s| class="text-red" id="form1" disabled|} == Utils.runtime_attrs(attrs_kw) end end end diff --git a/test/temple_test.exs b/test/temple_test.exs index fe9339c..bc7b3ee 100644 --- a/test/temple_test.exs +++ b/test/temple_test.exs @@ -89,7 +89,8 @@ defmodule TempleTest do div class: foo <> " bar" end - assert result == ~s{
">
} + assert result == + ~s| " bar")} %>>| end test "renders an attribute on a div passed as a variable as eex" do @@ -101,7 +102,7 @@ defmodule TempleTest do end assert result == - ~s{
} + ~s| x end))} %>>
| end test "renders a for comprehension as eex" do @@ -335,4 +336,20 @@ defmodule TempleTest do assert evaluate_template(result, assigns) == ~s{
foo

foo

bar

bar
} end + + test "boolean attributes" do + assigns = %{is_true: true, is_false: false} + + result = + temple do + input type: "text", disabled: true + input type: "text", disabled: false + + input type: "text", disabled: @is_true + input type: "text", disabled: @is_false + end + + assert evaluate_template(result, assigns) == + ~s{\n\n\n} + end end