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/README.md
2019-07-03 20:57:19 -04:00

4.6 KiB

Temple

Build Status

Temple is a DSL for writing HTML using Elixir.

You're probably here because you want to use Temple to write Phoenix templates, which is why Temple includes a Phoenix template engine and Temple-compatible Phoenix form helpers.

Installation

If available in Hex, the package can be installed by adding temple to your list of dependencies in mix.exs:

def deps do
  [
    {:temple, "~> 0.1.0"}
  ]
end

Usage

use Temple

htm do
  h2 "todos"

  ul class: "list" do
    for item <- @items do
      li class: "item" do
        div class: "checkbox" do
          div class: "bullet hidden"
        end

        div item
      end
    end
  end

  script """
  function toggleCheck({currentTarget}) {
    currentTarget.children[0].children[0].classList.toggle("hidden");
  }

  let items = document.querySelectorAll("li");

  Array.from(items).forEach(checkbox => checkbox.addEventListener("click", toggleCheck));
  """
end

Components

Temple provides an API for creating custom components that act as custom HTML elements.

These components can be given props that are available inside the component definition as module attributes. The contents of a components do block are available as a special @children attribute.

defcomponent :flex do
  div id: @id, class: "flex" do
    @children
  end
end

htm do
  flex id: "my-flex" do
    div "Item 1"
    div "Item 2"
    div "Item 3"
  end
end

Phoenix.HTML

Temple provides macros for working with the helpers provided by the Phoenix.HTML package.

Most of the macros are purely wrappers, while the semantics of some are changed to work with Temple.

htm do
  form_for @conn, Routes.some_path(@conn, :create) do
    text_input form, :name
  end
end

Phoenix templates

Add the templating engine to your Phoenix configuration.

# config.exs
config :phoenix, :template_engines, exs: Temple.Engine

# your_app_web.ex
def view do
  quote do
    # ...
    use Temple # Replaces the call to import Phoenix.HTML
  end
end
# app.html.exs
html lang: "en" do
  head do
    meta charset: "utf-8"
    meta http_equiv: "X-UA-Compatible", content: "IE=edge"
    meta name: "viewport", content: "width=device-width, initial-scale=1.0"
    title "YourApp · Phoenix Framework"

    link rel: "stylesheet", href: Routes.static_path(@conn, "/css/app.css")
  end

  body do
    header do
      section class: "container" do
        nav role: "navigation" do
          ul do
            li do: a("Get Started", href: "https://hexdocs.pm/phoenix/overview.html")
          end
        end

        a href: "http://phoenixframework.org/", class: "phx-logo" do
          img src: Routes.static_path(@conn, "/images/phoenix.png"),
              alt: "Phoenix Framework Logo"
        end
      end
    end

    main role: "main", class: "container" do
      p get_flash(@conn, :info), class: "alert alert-info", role: "alert"
      p get_flash(@conn, :error), class: "alert alert-danger", role: "alert"

      partial render(@view_module, @view_template, assigns)
    end

    script type: "text/javascript", src: Routes.static_path(@conn, "/js/app.js")
  end
end

Formatter

Add the following to your .formatter.exs to unsure that the Temple DSL functions are formatted without parens.

temple_funcs = ~w[
  html htm
  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
  map svg math
  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
  meta link base
  area br col embed hr img input keygen param source track wbr
  text partial

  form_for inputs_for
  checkbox color_input checkbox color_input date_input date_select datetime_local_input
  datetime_select email_input file_input hidden_input number_input password_input range_input
  search_input telephone_input textarea text_input time_input time_select url_input
  reset submit phx_label multiple_select select phx_link phx_button
]a |> Enum.map(fn e -> {e, :*} end)

[
  inputs: ["*.{ex,exs}", "{config,lib,test}/**/*.{ex,exs}"],
  locals_without_parens: temple_funcs
]