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:
- 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 ofPhoenixFuentes.AccountController
. - 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!