Whooo welcome! Didn’t expect you here. ^.^
I…may push it around a lot here, I really find it’s API to be well designed (though I do wish I could feed it through my rollup packaging system, it doesn’t follow the JS module spec). ^.^;
Yep plugs and an api for querying and setting things. I’ve made enough of what I’ve needed in my own project. I’ve intended to pull it out for a while now and document it, but it is so super easy for anyone to make theirselves that I’ve not really gotten around to it yet… ^.^;
My file as it stands, I don’t use ‘all’ of it so I cannot claim it all to be tested, and of course it’s missing a lot of obvious helpers that I otherwise do randomly in my code (bad form I know) so it does need some work on it (it’s an internal file…), but this is what I have so far in an unpoly.ex
file:
defmodule Unpoly do
def up?(conn), do: target(conn) !== nil
# defdelegate unpoly?, to: up?
def target(conn), do: List.keyfind(conn.req_headers, "x-up-target", 0, nil)
def target?(conn, tested_target) when is_binary(tested_target) do
if up?(conn) do
case target(conn) do
^tested_target -> true
"html" -> true
"body" -> not (tested_target in ["head", "title", "meta"])
_ -> false
end
else
true
end
end
def validate?(conn), do: validate_name(conn) !== nil
def validate_name(conn), do: List.keyfind(conn.req_headers, "x-up-validate", 0, nil)
def set_title(conn, new_title) when is_binary(new_title), do: Plug.Conn.put_resp_header(conn, "x-up-title", new_title)
defmodule Plugs do
defmodule RequestMethodCookie do
@cookie_name "_up_method"
def init(options), do: options
def call(conn, params) do
case conn.method do
"GET" -> Plug.Conn.delete_resp_cookie(conn, @cookie_name, List.wrap(params[:cookie_opts]))
method -> Plug.Conn.put_resp_cookie(conn, @cookie_name, method, List.wrap(params[:cookie_opts]))
end
end
end
defmodule RequestEchoHeaders do
def init(options), do: options
def call(conn, params) do
conn
# |> Plug.Conn.put_resp_header("x-up-location", conn.request_path)
# |> Plug.Conn.put_resp_header("x-up-method", conn.method)
end
end
defmodule AddRedirectHeaderAfter do
def init(options), do: options
def call(conn, params) do
case Plug.Conn.get_resp_header(conn, "location") do
location when is_binary(location) -> Plug.Conn.put_resp_header(conn, "x-up-location", location)
end
end
end
end
end
To package it you just run mix new unpoly
and follow the steps, the replace the pre-built lib/unpoly.ex
with the above (edited to add documentation and all such too of course).
For testing you would want to inlcude the Plug library as a testing only dependency and use it’s test helpers to test that things go through properly as expected either in doctests, or the dedicated test file(s) in the test/*
directory. I’m sure someone here could create a whole scaffold project if you want.
Once it’s made you’ll want to include ex_doc
as a dev-only dependency then you’ll be able to publish it to the hex package system with documentation and all (and of course you can keep the whole project directory inside the unpoly project if you preferred too).