Packages
surface
0.9.2
0.12.3
0.12.2
0.12.1
0.12.0
0.11.5
0.11.4
0.11.3
0.11.2
0.11.1
0.11.0
0.10.0
0.9.5
0.9.4
0.9.3
0.9.2
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.6
0.7.5
0.7.4
0.7.3
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.2
0.5.1
0.5.0
0.4.1
0.4.0
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.1.0-alpha.2
0.1.0-alpha.1
0.1.0-alpha.0
A component based library for Phoenix LiveView
Current section
Files
Jump to
Current section
Files
lib/surface/renderer.ex
defmodule Surface.Renderer do
@moduledoc false
defmacro __before_compile__(env) do
render? = Module.defines?(env.module, {:render, 1})
slotable? = Module.defines?(env.module, {:__slot_name__, 0})
root = Path.dirname(env.file)
filename = template_filename(env)
template = Path.join(root, filename)
template_ast =
if File.exists?(template) do
env = Map.put(env, :function, {:render, 1})
template
|> File.read!()
|> Surface.Compiler.compile(1, env, template)
|> Surface.Compiler.to_live_struct()
else
nil
end
case {render?, slotable?, File.exists?(template)} do
{true, _, true} ->
quote do
@doc """
Renders the colocated .sface file with the given `assigns`
Use this function when you need to override assigns for colocated
templates.
## Example
def render(assigns) do
assigns = assign(assigns, value: "123")
render_sface(assigns)
end
"""
@file unquote(template)
@external_resource unquote(template)
def render_sface(var!(assigns)) do
unquote(template_ast)
end
end
{true, _, false} ->
:ok
{false, _, true} ->
quote do
@file unquote(template)
@external_resource unquote(template)
def render(var!(assigns)) do
unquote(template_ast)
end
def __template_file__(), do: unquote(template)
end
{_, true, _} ->
:ok
_ ->
message = ~s'''
render/1 was not implemented for #{inspect(env.module)}.
Make sure to either explicitly define a render/1 clause with a Surface template:
def render(assigns) do
~F"""
...
"""
end
Or create a file at #{inspect(template)} with the Surface template.
'''
IO.warn(message, Macro.Env.stacktrace(env))
quote do
@external_resource unquote(template)
def render(_assigns) do
raise unquote(message)
end
end
end
end
defp template_filename(env) do
env.module
|> Module.split()
|> List.last()
|> Macro.underscore()
|> Kernel.<>(".sface")
end
end