Don't recursively call generated component macros (#12)

Recursively calling the macros works fine if you `import` the whole
module wherever you are using your components, but not if you `require`
the module.

This is because importing brings in the all the macros into the callers
namespace, which allows them to be called just by the macro name. When
you `require` the module, it will look for the generated 2-arity macro
in the callers namespace, which probably doesn't exist.

We get around this by not recursively calling them and avoiding the
problem all togther. A few utility functions solves the original issue
of wanting to DRY the file.
This commit is contained in:
Mitchell Hanberg 2019-08-10 01:09:24 -04:00 committed by GitHub
parent 030e0f9d3c
commit eb0fde6e83
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 45 additions and 17 deletions

View file

@ -1,5 +1,11 @@
# Changelog
## Master
### Bugfixes
- Allow components to be used correctly when their module was `require`d instead of `import`ed
## 0.1.1
### Bugfixes

View file

@ -148,39 +148,33 @@ defmodule Temple do
defmacro unquote(name)() do
outer = unquote(Macro.escape(block))
quote do
_ = unquote(outer)
end
Temple.Utils.__quote__(outer)
end
defmacro unquote(name)(props_or_block)
defmacro unquote(name)([{:do, inner}]) do
name = unquote(name)
outer =
unquote(Macro.escape(block))
|> Temple.Utils.__insert_props__([], inner)
quote do
unquote(name)([], unquote(inner))
end
Temple.Utils.__quote__(outer)
end
defmacro unquote(name)(props) do
name = unquote(name)
outer =
unquote(Macro.escape(block))
|> Temple.Utils.__insert_props__(props, nil)
quote do
unquote(name)(unquote(props), nil)
end
Temple.Utils.__quote__(outer)
end
defmacro unquote(name)(props, inner) do
outer =
unquote(Macro.escape(block))
|> Macro.prewalk(&Temple.Utils.insert_props(&1, props, inner))
|> Temple.Utils.__insert_props__(props, inner)
name = unquote(name)
quote do
_ = unquote(outer)
end
Temple.Utils.__quote__(outer)
end
end
end

View file

@ -60,4 +60,13 @@ defmodule Temple.Utils do
|> Phoenix.HTML.html_escape()
|> Phoenix.HTML.safe_to_string()
end
def __quote__(outer) do
quote do: unquote(outer)
end
def __insert_props__(block, props, inner) do
block
|> Macro.prewalk(&Temple.Utils.insert_props(&1, props, inner))
end
end

View file

@ -3,6 +3,25 @@ defmodule TempleTest do
use Temple
describe "custom component" do
test "defcomponent works when requiring the module" do
require Component, as: C
{:safe, result} =
temple do
C.flex()
C.flex([])
C.flex([], [])
C.flex do
text "hi"
end
end
assert result ==
~s{<div class="flex"></div><div class="flex"></div><div class="flex"></div><div class="flex"></div>}
end
test "defines a basic component" do
import Component