4 ms·
Is it possible to get on Phoenix nested controllers? Like in remix.run, where for each route segment we get one controller/view. It’s really generalised version
by dhucerbin 3y ago
Is it possible to get on Phoenix nested controllers? Like in remix.run, where for each route segment we get one controller/view. It’s really generalised version of layouts.
When I was looking into Phoenix all routes, no matter how nested, had to resolve to single controller. That meant that controller for path `/user/settings/privacy` was also responsible for getting data to display users sidebar.
- sodapopcan 3y agoIn LiveView you can use hooks or LiveComponents for that kind of thing. Not sure about regular controllers as I've never actually built an app using them, heh.
- deleted 3y ago[deleted]
- arrowsmith 3y agoSounds like you want to define some shared behaviour that can be applied across a set of controllers? Phoenix doesn't have "nested" controllers like you describe, but you might be able to do what you want using a plug. Something like: # lib/your_app_web/controllers/user_sidebar.ex defmodule YourAppWeb.UserSidebar do def load_sidebar(conn, _params) do data = SomeModule.whatever_loads_your_sidebar_data() assign(conn, :sidebar, data) end end # then in router.ex: import YourAppWeb.UserSidebar pipeline :users do plug :load_sidebar end scope "/users", YourAppWeb do pipe_through [:browsers, :user] get "settings/privacy", SettingsController, :privacy # and all other routes that need this sidebar # … end Then in your controller action `SettingsController.privacy/2`, the incoming `conn` will already have `sidebar` assigned because it's been passed through `load_sidebar`. Remember that an HTTP request/response cycle in Phoenix is fundamentally just a list of transformations that are applied to a `%Plug.Conn{}`. If you want the same behaviour to apply to multiple controller actions, you can just define that behaviour in a plug function (i.e. a two-arity function that takes and returns a conn), then pass your conn through that plug before it reaches your controller actions.
- arrowsmith 3y agoTypo, too late to edit it now, but `pipe_through [:browsers, :user]` should be `pipe_through [:browsers, :users]` (i.e. `:users` not `:user`.)