View Source Hypa.Plug (Hypa v0.2.0)

A Plug offering functions useful for applications using HTMX.

This plug invokes the following function plugs:

The following functions are also invoked if Phoenix.Controller is present at compile-time:

  • put_htmx_layout/2 - Disables the root and app layouts if responding to an htmx request

Summary

Functions

Adds htmx to the response's cache headers in order for caching to work correctly.

Callback implementation for Plug.call/2.

Extracts HTMX headers into the conn's assigns.

Callback implementation for Plug.init/1.

Disable Phoenix layouts in responses to htmx requests.

Functions

Link to this function

add_htmx_cache_control(conn, opts)

View Source

Adds htmx to the response's cache headers in order for caching to work correctly.

Examples

iex> conn(:get, "/hello")
...> |> Hypa.Plug.add_htmx_cache_control(Hypa.Plug.init([]))
...> |> get_resp_header("vary")
["hx-request"]

Callback implementation for Plug.call/2.

Link to this function

detect_htmx_request(conn, opts)

View Source

Extracts HTMX headers into the conn's assigns.

See Request Headers Reference for documentation on htmx's header values.

Examples

iex> conn(:get, "/hello")
...> |> merge_req_headers([
...>      {"hx-request", "true"},
...>      {"hx-current-url", "/current"},
...>      {"hx-history-restore-request", "false"},
...>      {"hx-target", "my-target-element-id"},
...>      {"hx-trigger-name", "my-triggered-element-name"},
...>      {"hx-trigger", "my-triggered-element-id"}
...>    ])
...> |> Hypa.Plug.detect_htmx_request(Hypa.Plug.init([]))
...> |> Map.get(:assigns)
...> |> Map.get(:htmx)
%{
  request: true,
  boosted: false,
  current_url: "/current",
  history_restore_request: false,
  prompt: nil,
  target: "my-target-element-id",
  trigger: "my-triggered-element-id",
  trigger_name: "my-triggered-element-name"
}

If the request does not have htmx headers, the :htmx assign will not be present.

iex> conn(:get, "/htmxless")
...> |> Hypa.Plug.detect_htmx_request(Hypa.Plug.init([]))
...> |> Map.get(:assigns)
...> |> Map.has_key?(:htmx)
false

Callback implementation for Plug.init/1.

Link to this function

put_htmx_layout(conn, opts)

View Source

Disable Phoenix layouts in responses to htmx requests.

Only available when Phoenix is available.

Examples

The root layout (usually containing <head> content) is disabled for all htmx requests.

iex> conn(:get, "/hello")
...> |> assign(:htmx, %{request: true})
...> |> Hypa.Plug.put_htmx_layout(Hypa.Plug.init([]))
...> |> Phoenix.Controller.root_layout("html")
false

Usually, the app layout is disabled for htmx requests as well.

iex> conn(:get, "/hello")
...> |> assign(:htmx, %{request: true})
...> |> Hypa.Plug.put_htmx_layout(Hypa.Plug.init([]))
...> |> Phoenix.Controller.layout("html")
false

However, requests made using hx-boost are given the app layout. The root layout is still disabled for boosted requests.

iex> conn(:get, "/hello")
...> |> Phoenix.Controller.put_layout(html: {MyApp.Layouts, :app})
...> |> assign(:htmx, %{request: true, boosted: true})
...> |> Hypa.Plug.put_htmx_layout(Hypa.Plug.init([]))
...> |> Phoenix.Controller.layout("html")
{MyApp.Layouts, :app}

This is also the case for history restore requests. The root layout is disabled for history restore requests as well.

iex> conn(:get, "/hello")
...> |> Phoenix.Controller.put_layout(html: {MyApp.Layouts, :app})
...> |> assign(:htmx, %{request: true, history_restore_request: true})
...> |> Hypa.Plug.put_htmx_layout(Hypa.Plug.init([]))
...> |> Phoenix.Controller.layout("html")
{MyApp.Layouts, :app}