-
Notifications
You must be signed in to change notification settings - Fork 0
Description
I suggest to start with the desired usages.
I really like an idea that the API should be very close to the Phoenix routes. So we can possibly reuse a lot of Plugs and other packages in the future.
And I think that declarative API would not work here. It may sound strange, but looking back on django's admin panel, when we had a lot of functions, classes, custom handlers and monkey-patching, it is clear enough for me that it is not going to work well on complicated use-cases.
It should be extensible enough to cover all possible needs.
So my original idea was to follow phoenix way on doing things: MVC with templates.
Models
We should support ecto as an industry-standard.
Example model:
# model.ex
defmodule User do
schema "users" do
field :username, :string
field :password_hash, :string
field :active, :boolean, default: true
field :password, :string, virtual: true
field :password_confirmation, :string, virtual: true
timestamps
end
@required_fields ~w(username password password_confirmation)
@required_for_login_fields ~w(username password)
@optional_fields ~w(active)
endScenario 1
# router.ex
defmodule TestProject.Router do
use TestProject.Web, :router
use PhoenixAdmin.Router
# Pipelines:
pipeline :browser do
plug :accepts, ["html"]
plug :fetch_session
plug :fetch_flash
plug :protect_from_forgery
plug :put_secure_browser_headers
plug Guardian.Plug.VerifySession
plug Guardian.Plug.LoadResource
end
pipeline :require_auth do
plug Guardian.Plug.EnsureAuthenticated,
handler: TestProject.AuthController
end
# Scopes:
scope "/admin", PhoenixAdmin do
pipe_through :browser
# We will reuse standard ways to handle auth:
pipe_through :require_auth
scope "/user" do
# Registering model for our basic CRUD controller,
# note, that we are using almost the same DSL as Phoenix itself.
# `crud_for_model` (name is not important at the moment) will generate simple form
# for this schema and use it to
crud_for_model User, PhoenixAdminCRUDController, [:new, :create, :update, :destroy]
end
end
endThis scenario shows several things:
- It is easy to reuse basic
plugs written forphoenix - It is quite understandable and easy to use if you only know
phoenix - It follows the same ideas
Scenario 2
# router.ex
defmodule TestProject.Router do
# Copies the same code as the first scenario
# Scopes:
scope "/admin", PhoenixAdmin do
pipe_through :browser
# We will reuse standard ways to handle auth:
pipe_through :require_auth
scope "/user" do
# The main difference is here, instead of using our controller, it is possible to provide
# your own one and use pure `phoenix` API with a bit of our magic.
crud_for_model User, CustomController, [:new, :create, :destroy, :deactivate] # :deactivate is a custom method created in `CustomController`
end
end
end
# controllers/custom_controller.ex
defmodule TestPorject.CustomController do
use PhoenixAdmin.CustomController
# :new, :create, :destroy are already in context
def deactivate(conn, params) do
# Calling to some business-logic:
TestPorject.Utils.deactivate(params)
# Our wrapper around Phonix'es `render()`
admin_render(conn)
end
endThis scenario shows us the ease of overloading some methods or providing custom methods to the admin panel.