marcin
Phoenix 1.7 and inversion of control to render a sidebar
Hi!
I’m trying to have a layout in Phoenix 1.7, where besides @inner_content I also have a dynamic sidebar.
The content of the sidebar should depend on the view. How should I approach this? The last place where I can affect the sidebar is a controller I guess - i can set the assigns[:sidebar_content] and then read this in sidebar component.
However, it seems more elegant to set the sidebar content in the view – the controller assigns data, and the view decides how it is displayed in @inner_content and in the sidebar.
Is such inversion of control flow possible?
Most Liked
josevalim
Another approach is to have two app layouts. One for regular users and another for admin. Any logic or markup shared between the layouts can be moved to the root layout or into function components. So the layouts are very similar, except for the sidebar.
mssantosdev
You can send a Phoenix Component in the controller assigns instead of sending the sidebar content.
In your controller:
defmodule NewPhoenixWeb.PageController do
use NewPhoenixWeb, :controller
def home(conn, _params) do
render(conn, :home, sidebar_content: apply(NewPhoenixWeb.Layouts, :default_sidebar, [[]]))
end
def test(conn, _params) do
render(conn, :test, sidebar_content: apply(NewPhoenixWeb.Layouts, :admin_sidebar, [[]]))
end
end
In your layouts.ex:
defmodule NewPhoenixWeb.Layouts do
use NewPhoenixWeb, :html
embed_templates "layouts/*"
def default_sidebar(assigns) do
~H"""
<p>default sidebar</p>
"""
end
def admin_sidebar(assigns) do
~H"""
<p>admin sidebar</p>
"""
end
end
(There’s probably a better place for the above code, but layouts.ex exists in all Phoenix 1.7 apps.)
Finally, in your root.html.heex (or any other layout file you want to use):
<aside class="sidebar">
<%= @sidebar_content %>
</aside>
If your sidebar is a component, you can use slots instead.
defmodule NewPhoenixWeb.Layouts do
slot :inner_block
def sidebar(assigns) do
~H"""
<aside>
<%= render_slot(@inner_block) %>
</aside>
"""
end
end
<.sidebar>
<%= @sidebar_content %>
</.sidebar>
Things can get complicated depending on the number of sidebar variations, but it can be a good start.
Popular in Questions
Other popular topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #deployment
- #library
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #channels
- #elixirconf
- #exunit
- #discussion
- #code-sync
- #javascript
- #podcasts
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixir-ls
- #phoenix_html
- #iex
- #blog-post
- #graphql
- #genstage
- #ai
- #websockets
- #supervisor
- #advent-of-code
- #elixirconf-us
- #distillery
- #processes
- #forms
- #api
- #metaprogramming
- #security
- #performance









