From 06cbdd80ff997a2190419c9f9a29dde10657420e Mon Sep 17 00:00:00 2001 From: Mitchell Hanberg Date: Fri, 10 May 2019 15:06:03 -0400 Subject: [PATCH] form_for and text_input macros --- lib/dsl/html.ex | 58 +++++++++++++++++++++++++++++++++++++++--- mix.exs | 7 +++-- test/dsl/html_test.exs | 51 +++++++++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 6 deletions(-) diff --git a/lib/dsl/html.ex b/lib/dsl/html.ex index f4ab181..296035f 100644 --- a/lib/dsl/html.ex +++ b/lib/dsl/html.ex @@ -25,7 +25,9 @@ defmodule Dsl.Html do area br col embed hr img input keygen param source track wbr ]a + @doc false def nonvoid_elements, do: @nonvoid_elements + @doc false def void_elements, do: @void_elements @doc """ @@ -55,6 +57,7 @@ defmodule Dsl.Html do quote do import Kernel, except: [div: 2] import HTML.Link, except: [link: 1, link: 2] + import HTML.Form, only: [] {:ok, var!(buff, Dsl.Html)} = Utils.start_buffer([]) @@ -200,12 +203,59 @@ defmodule Dsl.Html do end end - end - - - + @doc """ + Generates an empty form tag. + See `Dsl.Html.form_for/4` for more details + """ + defmacro form_for(form_data, action) do + quote do + form_for(unquote_splicing([form_data, action]), []) end end + @doc """ + Generates a form tag with a form builder and a block. + + The form builder will be available inside the block through the `form` variable. + + This is a wrapper around the `Phoenix.HTML.Form.form_for/4` function and accepts all of the same options. + + ## Example + + ``` + htm do + form_for @conn, Routes.some_path(@conn, :create) do + text_input form, :name + end + end + + # {:safe, + # "
+ # + # + # + #
"} + ``` + """ + defmacro form_for(form_data, action, opts \\ [], block) do + quote do + var!(form) = HTML.Form.form_for(unquote_splicing([form_data, action, opts])) + + Utils.put_buffer(var!(buff, Dsl.Html), var!(form) |> HTML.Safe.to_iodata()) + _ = unquote(block) + Utils.put_buffer(var!(buff, Dsl.Html), "") + end + end + + @doc """ + Please see `Phoenix.HTML.Form.text_input/3` for details. + """ + defmacro text_input(form, field, opts \\ []) do + quote do + {:safe, input} = HTML.Form.text_input(unquote_splicing([form, field, opts])) + + Utils.put_buffer(var!(buff, Dsl.Html), input) + end + end end diff --git a/mix.exs b/mix.exs index e3402fa..fc8f93f 100644 --- a/mix.exs +++ b/mix.exs @@ -13,7 +13,10 @@ defmodule Dsl.MixProject do source_url: "https://github.com/mhanberg/cogent", docs: [ main: "Dsl", - extras: ["README.md"] + extras: ["README.md"], + deps: [ + phoenix_html: "https://hexdocs.pm/phoenix_html/" + ] ], dialyzer: [plt_add_apps: [:mix, :phoenix, :html_sanitize_ex]] ] @@ -35,7 +38,7 @@ defmodule Dsl.MixProject do [ {:phoenix_html, "~> 2.13"}, {:ex_doc, "~> 0.0", only: [:dev], runtime: false}, - {:html_sanitize_ex, "~> 1.3", only: [:dev], runtime: false}, + {:html_sanitize_ex, "~> 1.3", only: [:dev, :test], runtime: false}, {:phoenix, "~> 1.4", optional: true}, {:plug, "~> 1.8", optional: true}, {:dialyxir, "~> 1.0.0-rc.6", only: [:dev], runtime: false} diff --git a/test/dsl/html_test.exs b/test/dsl/html_test.exs index 79e3a0a..58016c8 100644 --- a/test/dsl/html_test.exs +++ b/test/dsl/html_test.exs @@ -399,4 +399,55 @@ defmodule Dsl.HtmlTest do assert result == ~s{
} end end + + describe "form_for" do + test "returns a form tag" do + conn = %Plug.Conn{} + action = "/" + + {:safe, result} = + htm do + form_for(conn, action, []) + end + + assert result =~ ~s{} + end + + test "can take a block" do + conn = %Plug.Conn{} + action = "/" + opts = [] + + {:safe, result} = + htm do + form_for conn, action, opts do + div() + end + end + + assert result =~ ~s{} + assert result =~ ~s{} + end + + test "can take a block that references the form" do + conn = %Plug.Conn{} + action = "/" + opts = [] + + {:safe, result} = + htm do + form_for conn, action, opts do + text_input(form, :bob) + end + end + + assert result =~ ~s{} + end + end end