5150a93e38
- requires the development branch of live_view currently, if you are going to be using live view ci Docs Raise minimum elixir version to 1.9 There is some bug in EEx that was fixed in 1.9 and I can't be bothered to make it backwards compatible with the bug. ugh Remove commented out line
179 lines
3.5 KiB
Elixir
179 lines
3.5 KiB
Elixir
defmodule Temple do
|
|
alias Temple.Parser
|
|
|
|
@moduledoc """
|
|
Temple syntax is available inside the `temple`, and is compiled into EEx at build time.
|
|
|
|
## Usage
|
|
|
|
```elixir
|
|
temple do
|
|
# You can define attributes by passing a keyword list to the element, the values can be literals or variables.
|
|
class = "text-blue"
|
|
id = "jumbotron"
|
|
|
|
div class: class, id: id do
|
|
# Text nodes can be emitted as string literals or variables.
|
|
"Bob"
|
|
|
|
id
|
|
end
|
|
|
|
# if and unless expressions can be used to conditionally render content
|
|
if 5 > 0 do
|
|
p do
|
|
"Greater than 0!"
|
|
end
|
|
end
|
|
|
|
unless 5 > 0 do
|
|
p do
|
|
"Less than 0!"
|
|
end
|
|
end
|
|
|
|
# You can loop over items using for comprehensions
|
|
for x <- 0..5 do
|
|
div do
|
|
x
|
|
end
|
|
end
|
|
|
|
# You can use multiline anonymous functions, like if you're building a form in Phoenix
|
|
form_for @changeset, Routes.user_path(@conn, :create), fn f ->
|
|
"Name: "
|
|
text_input f, :name
|
|
end
|
|
|
|
# You can explicitly emit a tag by prefixing with the Temple module
|
|
Temple.div do
|
|
"Foo"
|
|
end
|
|
|
|
# You can also pass children as a do key instead of a block
|
|
div do: "Alice", class: "text-yellow"
|
|
end
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Mode
|
|
|
|
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".
|
|
|
|
```elixir
|
|
config :temple, :mode, :normal # default
|
|
|
|
# or
|
|
|
|
config :temple, :mode, :live_view
|
|
```
|
|
|
|
### Aliases
|
|
|
|
You can add an alias for an element if there is a namespace collision with a function. If you are using `Phoenix.HTML`, there will be namespace collisions with the `<link>` and `<label>` elements.
|
|
|
|
```elixir
|
|
config :temple, :aliases,
|
|
label: :_label,
|
|
link: :_link,
|
|
select: :_select
|
|
|
|
temple do
|
|
_label do
|
|
"Email"
|
|
end
|
|
|
|
_link href: "/css/site.css"
|
|
end
|
|
```
|
|
|
|
This will result in:
|
|
|
|
```html
|
|
<label>
|
|
Email
|
|
</label>
|
|
|
|
<link href="/css/site.css">
|
|
```
|
|
"""
|
|
|
|
defmacro __using__(_) do
|
|
quote location: :keep do
|
|
import Temple
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Context for temple markup.
|
|
|
|
Returns an EEx string that can be passed into an EEx template engine.
|
|
|
|
## Usage
|
|
|
|
```elixir
|
|
import Temple
|
|
|
|
temple do
|
|
div class: @class do
|
|
"Hello, world!"
|
|
end
|
|
end
|
|
|
|
# <div class="<%= @class %>">
|
|
# Hello, world!
|
|
# </div>
|
|
```
|
|
"""
|
|
defmacro temple([do: block] = _block) do
|
|
markup =
|
|
block
|
|
|> Parser.parse()
|
|
|> Enum.map(&Temple.Generator.to_eex/1)
|
|
|> :erlang.iolist_to_binary()
|
|
|
|
quote location: :keep do
|
|
unquote(markup)
|
|
end
|
|
end
|
|
|
|
defmacro temple(block) do
|
|
quote location: :keep do
|
|
unquote(block)
|
|
|> Parser.parse()
|
|
|> Enum.map(&Temple.Generator.to_eex/1)
|
|
|> :erlang.iolist_to_binary()
|
|
end
|
|
end
|
|
|
|
@doc """
|
|
Compiles temple markup into a quoted expression using the given EEx Engine.
|
|
|
|
Returns the same output that Phoenix templates output into the `render/1` function of their view modules.
|
|
|
|
## Usage
|
|
|
|
```elixir
|
|
require Temple
|
|
|
|
Temple.compile Phoenix.HTML.Engine do
|
|
div class: @class do
|
|
"Hello, world!"
|
|
end
|
|
end
|
|
|
|
```
|
|
"""
|
|
defmacro compile(engine, [do: block] = _block) do
|
|
markup =
|
|
block
|
|
|> Parser.parse()
|
|
|> Enum.map(&Temple.Generator.to_eex/1)
|
|
|> :erlang.iolist_to_binary()
|
|
|
|
EEx.compile_string(markup, engine: engine, line: __CALLER__.line, file: __CALLER__.file)
|
|
end
|
|
end
|