elixir-web / weber

[WiP] Web framework for Elixir inspired by Rails [#WeberMVC at freenode]
http://elixir-web.github.io/weber/
MIT License
372 stars 33 forks source link

[Proposal] before/after hooks #138

Closed slogsdon closed 10 years ago

slogsdon commented 10 years ago

I wanted to judge interest in before and after filters that would allow for actions taken on the response for all controller methods. If this is something that is desired, I would like to start the discussion for finding a plan-of-action to suit Weber's goals/needs the best and, eventually, contribute the necessary changes.

Example

With controller:

defmodule Controllers.Main do
  use Weber.Controller
  layout false

  def index([], _conn) do
    {:render, []}
  end

  def page2([], _conn) do
    {:render, []}
  end

  def before(conn) do
    case Lib.Session.check(conn) do
      false -> {:redirect, "/login"}
      true -> conn
    end
  end
end

and routes:

route on("GET", "/", Controllers.Main, :index)
  |> on("GET", "/page2", Controllers.Main, :page2)

When the router matches / or /page2, it would call Controller.Main.before followed by the necessary Controller.Main method. Controller.Main.before could also manipulate conn to affect the response later down the line. If Controller.Main.after existed, it would be called after.

See also
0xAX commented 10 years ago

Hi @slogsdon,

Good point, but i suggest:

defmodule Controllers.Main do

  def index([], _conn) do
    {:render, []}
  end

  def page2([], _conn) do
    {:render, []}
  end

  def before_index(conn) do
    case Lib.Session.check(conn) do
      false -> {:redirect, "/login"}
      true -> conn
    end
  end

  def after_index(conn) do
    case Lib.Session.check(conn) do
      false -> {:redirect, "/login"}
      true -> conn
    end
  end

  def before_page2(conn) do
    case Lib.Session.check(conn) do
      false -> {:redirect, "/login"}
      true -> conn
    end
  end

  def after_page2(conn) do
    case Lib.Session.check(conn) do
      false -> {:redirect, "/login"}
      true -> conn
    end
  end
end
slogsdon commented 10 years ago

@0xAX I think per-action hooks would be smart. Would you think it would be wise to have per-action and per-controller, allowing a developer to have as much control over the process as he/she desires?

kotedo commented 10 years ago

I'd say one per controller, with the function name passed in as a parameter, then one can create conditionals within the one function and keep the controller code clean.

slogsdon commented 10 years ago

Consider this my vote for having both. All frameworks that I have had experience with that use hooks of this nature have had both (or something similar for customization), leaving the choice to the developer for which suits his/her needs the best.

0xAX commented 10 years ago

[In progress now]