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/html.ex

109 lines
3.1 KiB
Elixir
Raw Normal View History

defmodule Temple.Html do
require Temple.Elements
2019-05-12 02:20:43 +00:00
@moduledoc """
The `Temple.Html` module defines macros for all HTML5 compliant elements.
2019-05-12 02:20:43 +00:00
`Temple.Html` macros must be called inside of a `Temple.temple/1` block.
*Note*: Only the lowest arity macros are documented. Void elements are defined as a 1-arity macro and non-void elements are defined as 0, 1, and 2-arity macros.
2019-07-04 02:05:50 +00:00
2019-05-12 02:20:43 +00:00
## Attributes
Html accept a keyword list or a map of attributes to be emitted into the element's opening tag. Multi-word attribute keys written in snake_case (`data_url`) will be transformed into kebab-case (`data-url`).
2019-05-12 02:20:43 +00:00
## Children
Non-void elements (such as `div`) accept a block that can be used to nest other tags or text nodes. These blocks can contain arbitrary Elixir code such as variables and for comprehensions.
If you are only emitting a text node within a block, you can use the shortened syntax by passing the text in as the first parameter of the tag.
## Example
```
2019-07-09 02:29:41 +00:00
temple do
2019-05-12 02:20:43 +00:00
# empty non-void element
div()
# non-void element with keyword list attributes
2019-05-12 02:20:43 +00:00
div class: "text-red", id: "my-el"
# non-void element with map attributes
div %{:class => "text-red", "id" => "my-el"}
2019-05-12 02:20:43 +00:00
# non-void element with children
div do
text "Hello, world!"
for name <- @names do
div data_name: name
end
end
# non-void element with a single text node
div "Hello, world!", class: "text-green"
# void elements
input name: "comments", placeholder: "Enter a comment..."
end
# {:safe,
2019-05-12 02:20:43 +00:00
# "<div></div>
# <div class=\"text-red\" id=\"my-el\"></div>
# <div>
# Hello, world!
# <div data-name=\"Alice\"></div>
# <div data-name=\"Bob\"></div>
# <div data-name=\"Carol\"></div>
# </div>
# <div class=\"text-green\">Hello, world!</div>
# <input name=\"comments\" placeholder=\"Enter a comment...\">"
# }
```
"""
2019-04-15 01:44:39 +00:00
@nonvoid_elements ~w[
head title style script
noscript template
body section nav article aside h1 h2 h3 h4 h5 h6
header footer address main
p pre blockquote ol ul li dl dt dd figure figcaption div
a em strong small s cite q dfn abbr data time code var samp kbd
sub sup i b u mark ruby rt rp bdi bdo span
ins del
iframe object video audio canvas
2019-05-10 19:27:59 +00:00
map
2019-04-15 01:44:39 +00:00
table caption colgroup tbody thead tfoot tr td th
form fieldset legend label button select datalist optgroup
option textarea output progress meter
details summary menuitem menu
]a
@void_elements ~w[
meta link base
area br col embed hr img input keygen param source track wbr
]a
2019-05-10 19:06:03 +00:00
@doc false
def nonvoid_elements, do: @nonvoid_elements
2019-05-10 19:06:03 +00:00
@doc false
def void_elements, do: @void_elements
2019-04-15 01:44:39 +00:00
for el <- @nonvoid_elements do
Temple.Elements.defelement(unquote(el), :nonvoid)
2019-04-15 01:44:39 +00:00
end
for el <- @void_elements do
Temple.Elements.defelement(unquote(el), :void)
2019-04-15 01:44:39 +00:00
end
defmacro html(attrs \\ [], [{:do, _inner}] = block) do
doc_type =
quote location: :keep do
Temple.Utils.put_buffer(var!(buff, Temple.Html), "<!DOCTYPE html>")
end
[doc_type, Temple.Elements.nonvoid_element(:html, attrs, block)]
end
2019-04-15 01:44:39 +00:00
end