Extending a Phoenix Application

Hi there!

Trying to determine what’s the right approach to extending a Phoenix app’s functionality.

I have a small hex package, Fuentes, for handling double-entry accounting. I’m looking to build another package, Phoenix_Fuentes, to allow people to integrate that functionality into their application. My intention was to have a PhoenixFuentes.AccountController as well as default views allowing people to just add resources "/accounts", PhoenixFuentes.AccountController to their router.ex and all would be right in the world.

I thought I’d be able to do something like:

defmodule PhoenixFuentes.AccountController do
  use (SomeFunctionToGetParentApp).Web, :controller

  def index(conn, _params) do
    render conn, "index.html"
  end
end

But was shown in the phoenix channel on slack how that might result in circular dependencies at compile time and just wasn’t a good idea.

Looking into the use macro, I see it calls (as generated):

      use Phoenix.Controller<%= if namespaced? do %>, namespace: <%= application_module %><% end %>
<%= if ecto do %>
      alias <%= application_module %>.Repo
      import Ecto
      import Ecto.Query
<% end %>
      import <%= application_module %>.Router.Helpers
      import <%= application_module %>.Gettext

so I can’t just duplicate it’s functionality as the library won’t know what application (the application_module) it is a dep of.

Accordingly, right now I’m seeing two options:

  1. A mix generator to copy templates of the account controller and account views to the parent app, to allow people to use TheirApp.AccountController instead of PhoenixFuentes.AccountController.
  2. A standalone phoenix application which is under an umbrella application.

I was intending to provide Option 1 to allow people the ability to customize controllers and views as needed, but was hoping there was a way to facilitate “trying it out” without needing to touch their own codebase. I’m also not sure if Option 2 is even a true option?

Has anyone encountered other Elixir libraries that try to accomplish this type of “extension” functionality?
Any other options or better ways of solving this problem that I should consider?

Thanks!