[![beauty inside!](](
[![Build Status](](
[![Coverage Status](](
[![ version](](
[![ downloads](](

DSL for creating html structure straight with Elixir blocks:

    use WebAssembly
    builder do
      html do
        head do
          meta http_equiv: "Content-Type", content: "text/html"
          title "example"
        body do
          div class: "container", id: :content do
            ul do
              for index <- 1..3, do:
                li "item #{index}"
            random = :random.uniform(10)
            if random == 5 do
              text "Lucky! You got five"
          span [style: "smiling"], "that was nice"

This results in a deeply nested list (aka [iolist])
which you can flatten or (better!) send to the socket as it is
([via Plug & Cowboy][via-plug] for example).

Now what can be concluded from the example above:

* you produce HTML elements by using macros inside `builder` block
* [non-void] element can be used with "flat" content argument or with a `do`-block
* element with a `do`-block means nesting
* inside such a `do`-block you have access to **full Elixir syntax**
* element attributes go first (but are optional), then the content
* attributes are Elixir keywords
* underscores in attribute keys are translated to dash signs
* you can omit brackets around attributes when using `do`-block,
  but not when using flat form
* [void] HTML elements correspond to macros with attributes only,
  like `meta` above
* if you want to emit just text without surrounding html tags,
  simply use `text` macro.

For me it's beautiful. What about you?

## Why?

* to have views in pure Elixir, without HTML templates
* to utilize Erlang's approach: you can feed sockets with iolists
  instead of one big binary produced by template engine

You can possibly mix different styles: code small snippets in
WebAssembly and feed them to your partial templates, finally using
your template engine to render the whole page.

## Usage

WebAssembly is published on [Hex], so just add `{:webassembly, "~> 0.6"}`
to your deps and `:webassembly` to your apps in the `mix.exs`.

Using it with [Plug] is a no-brainer - you just pass the doc to `send_resp/3`:

defmodule Plugged do
  import Plug.Conn
  use Plug.Router
  use WebAssembly

  plug :match
  plug :dispatch

  get "/" do
    doc = builder do
      html do
        body do
          text "hello from Plug!"
    |> put_resp_content_type("text/html")
    |> send_resp(200, doc)

API details are available at [hexdocs].

## TDD

WebAssembly aims to have 100% [test coverage][cov].

## Type Safety

As for releases `0.3.0` and above WebAssembly [dialyzes][dia] with no warnings.

## Thanks

Loosely inspired by [Markaby].

## License

The code is released under the BSD 2-Clause License.