Packages

A plug and play package for using Turbolinks with Elixir web frameworks

Retired package: Deprecated

Current section

Files

Jump to
turbolinks lib turbolinks.ex
Raw

lib/turbolinks.ex

defmodule Turbolinks do
@moduledoc """
This plug is built on top of works done by @kagux at https://github.com/kagux/turbolinks_plug
in `web.ex`
add `use Turbolinks`
in `router.ex` add a the plug
plug Turbolinks
"""
use Plug.Builder
import Turbolinks.Helpers
@session_key "turbolinks_location"
@original_location_header "location"
@location_header "turbolinks-location"
@referrer_header "turbolinks-referrer"
defmacro __using__(opts) do
quote bind_quoted: [opts: opts] do
import Phoenix.Controller, except: [redirect: 2]
import Turbolinks.Helpers
end
end
@doc false
def call(conn, opts) do
conn
|> super(opts)
|> register_before_send(&handle_redirect/1)
|> put_phoenix_format()
end
@doc false
defp handle_redirect(conn) do
case conn.status do
status when status in 301..302 ->
store_location_in_session(conn)
status when status in 200..299 ->
restore_location_from_session(conn)
_status ->
conn
end
end
defp store_location_in_session(conn) do
with [_referrer] <- get_referrer_header(conn),
[location] <- get_location_header(conn) do
put_session(conn, @session_key, location)
else
[] -> conn
end
end
defp restore_location_from_session(conn) do
if location = get_session(conn, @session_key) do
conn
|> put_resp_header(@location_header, location)
|> delete_session(@session_key)
else
conn
end
end
defp get_location_header(conn) do
get_resp_header(conn, @original_location_header)
end
defp get_referrer_header(conn) do
get_req_header(conn, @referrer_header)
end
defp put_phoenix_format(conn) do
if xhr?(conn) do
Phoenix.Controller.put_format(conn, "js")
else
conn
end
end
end