Different layout for logged in user based on role either admin or non-admin

I have installed Pow in Phoenix for user registration. I want to differentiate the URL and layout of my logged in users. If logged in as Admin I have created its role as admin while for normal logged in user it is User.

How can I provide the different layout to Admin user and Non-Admin users even I want to land them in different URLs lets for example for admin http://www.example.com/admin/ and for a non-admin user it will be like http://www.example.com/game.

I have read the route document of Phoenix at https://hexdocs.pm/phoenix/routing.html but not sure how to ensure that if it is admin then we need to use a new scope of admin. Can you provide me a code sample of it? Any URL which will help me on how to write code. I am beginner in this language.

You need to use Phoenix.Controller.put_layout/2. So assuming that you have different scopes for admin and non admin:

pipeline :admin do
  plug :set_layout, "admin"
end

scope "/admin" do
  pipe_through [:admin]
  # …
end

defp set_layout(conn, layout) do
  Phoenix.Controller.put_layout(conn, layout)
end

Thanks for the reply but how can I detect at route level that logged in user is admin or non-admin based on user role either ‘admin’ or ‘non-admin-user’

You could write a plug, which calls put_layout on the conn depending on the roles of the user stored on the conn.

2 Likes

put_layout is the right way to deal with custom templates for certain roles, but I think what you are asking for is how to redirect the user after sign in depending on the role.

You can customize the callback routes to redirect admin users: https://hexdocs.pm/pow/1.0.13/README.html#callback-routes

So you can do something like:

defmodule MyAppWeb.Pow.Routes do
  use Pow.Phoenix.Routes
  alias MyAppWeb.Router.Helpers, as: Routes

  def after_sign_in_path(conn) do
    user = Pow.Plug.current_user(conn)

    case user.role do
      "admin" -> Routes.admin_dashboard_path(conn, :index)
      _any    -> Routes.game_path(conn, :index)
  end
end

This will redirect admin users to the admin dashboard instead of the game page. Remember to add routes_backend: MyAppWeb.Pow.Routes to the config.

Thanks it works but has one issue any non-admin user if type /admin in the browser like https:///www.example.com/admin

it redirect that non-admin user to admin dashboard how can I prevent non-admin user to access admin user pages

You will need to add a plug restricting access like this: https://hexdocs.pm/pow/1.0.13/user_roles.html#add-role-plug

1 Like