david
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.AccountControllerinstead 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!
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #ai
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 1 to 1- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
chrismccord
It’s not clear why you need to do something like this within your library? What would the above achieve in the context of your controller? Instead, if you left it as
use Phoenix.Controller, what prevents that from working for you? You can serve the templates from your app as normal and it would just work. If the user wanted to override the templates, they could useput_view MyApp.MyFuentesViewin a pipeline that calls your router/controller? If you can give a better description on the kind of extension you’re going for, I can say more, but the injection approach from the “parent” app is not the right way to think about it