This repository has been archived on 2023-08-07. You can view files and clone it, but cannot push or open issues or pull requests.
temple/lib/temple.ex

169 lines
3.1 KiB
Elixir
Raw Normal View History

2019-07-02 02:48:51 +00:00
defmodule Temple do
2020-06-16 19:28:21 +00:00
alias Temple.Buffer
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
@moduledoc """
> Warning: Docs are WIP
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
Temple syntax is available inside the `temple` and `live_temple` macros, and is compiled into EEx at build time.
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
### Usage
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
```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"
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
div class: class, id: id do
# Text nodes can be emitted as string literals or variables.
"Bob"
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
id
end
# if and unless expressions can be used to conditionally render content
if 5 > 0 do
p do
"Greater than 0!"
2019-05-11 16:49:34 +00:00
end
end
2020-06-16 19:28:21 +00:00
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 call 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
2019-05-11 16:49:34 +00:00
```
2020-06-16 19:28:21 +00:00
### Reserved keywords
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
You can pass a keyword list to an element as element attributes, but there are several reserved keywords.
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
#### Compact
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
Passing `compact: true` will not rendering new lines from within the element. This is useful if you are trying to use the `:empty` psuedo selector.
```elixir
temple do
p compact: true do
"Foo"
end
p do
"Bar"
2019-05-11 16:49:34 +00:00
end
end
2020-06-16 19:28:21 +00:00
```
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
would evaluate to
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
```html
<p>Foo</p>
<p>
Bar
</p>
2019-05-11 16:49:34 +00:00
```
2020-06-16 19:28:21 +00:00
### Configuration
#### 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
2019-07-09 02:29:41 +00:00
temple do
2020-06-16 19:28:21 +00:00
_label do
"Email"
2019-05-11 16:49:34 +00:00
end
2020-06-16 19:28:21 +00:00
_link href: "/css/site.css"
2019-05-11 16:49:34 +00:00
end
2020-06-16 19:28:21 +00:00
```
This will result in:
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
```html
<label>
Email
</label>
<link href="/css/site.css">
2019-05-11 16:49:34 +00:00
```
"""
2020-06-16 19:28:21 +00:00
defmacro __using__(_) do
quote location: :keep do
2020-06-16 19:28:21 +00:00
import Temple
2019-05-11 16:49:34 +00:00
end
end
2020-06-16 19:28:21 +00:00
defmacro temple([do: block] = _block) do
{:ok, buffer} = Buffer.start_link()
buffer
2020-07-10 16:32:51 +00:00
|> Temple.Parser.Private.traverse(block)
2020-06-16 19:28:21 +00:00
markup = Buffer.get(buffer)
Buffer.stop(buffer)
quote location: :keep do
unquote(markup)
2019-05-11 16:49:34 +00:00
end
end
2020-06-16 19:28:21 +00:00
defmacro temple(block) do
quote location: :keep do
2020-06-16 19:28:21 +00:00
import Temple
2020-06-16 19:28:21 +00:00
{:ok, buffer} = Buffer.start_link()
2020-06-16 19:28:21 +00:00
buffer
2020-07-10 16:32:51 +00:00
|> Temple.Parser.Private.traverse(unquote(block))
2020-06-16 19:28:21 +00:00
markup = Buffer.get(buffer)
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
Buffer.stop(buffer)
2020-06-16 19:28:21 +00:00
markup
end
end
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
defmacro live_temple([do: block] = _block) do
{:ok, buffer} = Buffer.start_link()
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
buffer
2020-07-10 16:32:51 +00:00
|> Temple.Parser.Private.traverse(block)
2019-05-11 16:49:34 +00:00
2020-06-16 19:28:21 +00:00
markup = Buffer.get(buffer)
Buffer.stop(buffer)
EEx.compile_string(markup, engine: Phoenix.LiveView.Engine)
2019-05-11 16:49:34 +00:00
end
2019-04-15 01:44:39 +00:00
end