Skip to content

Example usages #1

@sobolevn

Description

@sobolevn

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)
end

Scenario 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
end

This scenario shows several things:

  1. It is easy to reuse basic plugs written for phoenix
  2. It is quite understandable and easy to use if you only know phoenix
  3. 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
end

This scenario shows us the ease of overloading some methods or providing custom methods to the admin panel.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions