Skip to content

Commit

Permalink
Page Builder - encode components with :let
Browse files Browse the repository at this point in the history
Render the enclosing element and halt early instead of
encoding each children, which fails since we don't
have the binding defined by :let in the outer context

Close BeaconCMS#485

Related to BeaconCMS/beacon_live_admin#111
  • Loading branch information
leandrocp authored and ddink committed May 10, 2024
1 parent eacd534 commit 3da0610
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
10 changes: 9 additions & 1 deletion lib/beacon/template/heex/json_encoder.ex
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,18 @@ defmodule Beacon.Template.HEEx.JSONEncoder do
end

defp transform_entry({:tag_block, tag, attrs, content, _} = node, site, assigns) do
has_let_in_attrs? =
Enum.reduce_while(attrs, false, fn
{":let", {:expr, _, _}, _}, _acc -> {:halt, true}
_attr, _acc -> {:cont, false}
end)

content = if has_let_in_attrs?, do: [], else: encode_tokens(content, site, assigns)

entry = %{
"tag" => tag,
"attrs" => transform_attrs(attrs),
"content" => encode_tokens(content, site, assigns)
"content" => content
}

maybe_add_rendered_html(site, assigns, node, entry)
Expand Down
28 changes: 28 additions & 0 deletions test/beacon/template/heex/json_encoder_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,34 @@ defmodule Beacon.Template.HEEx.JSONEncoderTest do
)
end

test "function component with special attribute :let" do
template = ~S|
<Phoenix.Component.form :let={f} for={%{}} as={:newsletter} phx-submit="join">
<input
id={Phoenix.HTML.Form.input_id(f, :email)}
name={Phoenix.HTML.Form.input_name(f, :email)}
class="text-sm"
placeholder="Enter your email"
type="email"
/>
<button type="submit">Join</button>
</Phoenix.Component.form>
|

assert_output(
template,
[
%{
"attrs" => %{":let" => "{f}", "as" => "{:newsletter}", "for" => "{%{}}", "phx-submit" => "join"},
"content" => [],
"rendered_html" =>
"<form phx-submit=\"join\">\n \n \n \n <input id=\"newsletter_email\" name=\"newsletter[email]\" class=\"text-sm\" placeholder=\"Enter your email\" type=\"email\">\n <button type=\"submit\">Join</button>\n\n</form>",
"tag" => "Phoenix.Component.form"
}
]
)
end

test "my_component" do
component_fixture(site: :my_site)
Beacon.Loader.fetch_components_module(:my_site)
Expand Down

0 comments on commit 3da0610

Please sign in to comment.