Data inside Phoenix partial template

Hi,

I have partial template called _sidebar.html.heex which I include in several different templates. This partial template loads some data from the database. Right now, inside controller of every template that uses this partial template, I have to load the necessary data so I could use it inside the sidebar. I have to repeat that same process for every template. Is there a more efficient way to load this data and make it accessible to sidebar?

Here’s just one example; I have to load notifications inside every controller function which includes sidebar partial template so I could use it.

def index(conn, _params, current_user) do
    notifications = Notifications.list_notifications(current_user)

    render(conn, "index.html", notifications: notifications)
  end

If you need it every page you could write a Plug to assign it to your conn, just as you did with current_user.

Something like this (not tested):

defmodule MyAppWeb.Plugs.Notifications do
  @behaviour Plug

  @impl Plug
  def init(opts), do: opts

  @impl Plug
  def call(conn, _opts \\ []) do
    if current_user = conn.assigns[:current_user] do
      notifications = MyApp.Notifications.list_notifications(current_user)
      assign(conn, :notifications, notifications)
    else
      assign(conn, :notifications, [])
    end
  end
end

then in your router:

pipeline :browser do
  ...
  plug MyAppWeb.Plugs.Notifications
end

EDIT:
After re-looking at your code, it does not look like you have current_user in the conn? You probably want to have another plug for that too, and placed before the Notifications plug in the pipeline.

2 Likes

To add to this answer, you can also apply it only to certain router scopes

scope "/", MyAppWeb do
  pipe_through [:browser, MyAppWeb.Plugs.Notifications]
  ...
end

Or per controller, optionally limited to certain actions

defmodule MyAppWeb.PageController do
  use MyAppWeb, :controller

  plug MyAppWeb.Plugs.Notifications
  # or
  plug MyAppWeb.Plugs.Notifications when action in [:index, :show]
  # or
  plug MyAppWeb.Plugs.Notifications when action not in [:create, :update, :delete]
  ...
end

https://hexdocs.pm/phoenix/plug.html#content

2 Likes