lib/xadmin/phx.ex

defmodule Xmeta.Xadmin.Phx do
  
  use Phoenix.Controller,formats: [:html, :json]
  import Plug.Conn

  def call_api(conn, params) do
    site = module_name_upcase(params["xadmin_site"])
    router = module_name_upcase(params["xadmin_router"])
    view = module_name_upcase(params["xadmin_view"])
    mod =
      Module.concat(["Xadmin", site, router, view])
    apply(mod, :call, [conn, format_params(conn.params)])
  end

  defp format_params(params) do
    params 
      |> Map.delete("glob") 
      |>Map.delete("xadmin_site") 
      |>Map.delete("xadmin_router") 
      |>Map.delete("xadmin_view") 
  end

  defp module_name_upcase(name) do
    {first,last} = String.next_grapheme(name)  
    String.upcase(first) <> last
  end

  def controller(conn, params) do
    rsp = Xmeta.Xadmin.Phx.call_api(conn,params)
    json(conn,rsp)
  end

  defmacro init_xadmin(path) do
    quote do
      scope unquote(path) do
        get "/:xadmin_site/:xadmin_router/:xadmin_view", Xmeta.Xadmin.Phx, :controller
        post "/:xadmin_site/:xadmin_router/:xadmin_view", Xmeta.Xadmin.Phx, :controller
      end
    end
  end
end