I’m building my first Phoenix app and need a little guidance.
Say I build a quiz maker.
Admin users may create questions and answers;
Visitors of the website can answer the questions.
I ran the following command to create my first context: mix phx.gen.html Quiz Question questions text:string
But what confuses me, is that I will have two clearly distinct sections of my website, with two different layouts: a layout and templates for admins, and a layout and templates for the visitors.
Most of these generated files such as the templates to list the questions, create/edit/delete a question, and so on should only be accessible by an admin user.
Also, the template to view a question show.html.eex will be different for an admin and a visitor: the visitor will have a nicely displayed question (with different html), while the admin will have a rather raw template, using the same layout as the layout used for listing questions and editing questions.
All of the admin templates will have a basic layout, while the templates for the visitors will have a layout with a nicer design.
The command above generates for exemple: lib/quiz_maker_web/templates/question/show.html.eex lib/quiz_maker_web/templates/question/form.html.eex ...
While I need something like: lib/quiz_maker_web/templates/admin/question/show.html.eex lib/quiz_maker_web/templates/admin/question/form.html.eex lib/quiz_maker_web/templates/guest/question/show.html.eex ...
I think my requirement is a pretty basic one, but I don’t know the best way to achieve it. Any help is very much appreciated!
Hi, you can make a separate pipeline in which you specify a different template for the layout, and then use that pipeline in the scope that contains the admin routes.
For example, define a separate layout in admin.html.eex, then configure your router something like:
pipeline :admin_pages do
plug(:accepts, ["html"])
plug :put_layout, {MyAppWeb.LayoutView, "admin.html"}
end
scope "/admin", MyAppWeb, as: :admin do
pipe_through(:admin_pages)
get("/", AdminController, :index)
end
Any pages served under /admin will get the admin layout.
I have a login page for the admin users, managed by Admin.SessionController and displayed by new action and /templates/admin/session/new.html.eex template. I’d like this page to have the admin layout like other admin pages, and be located under /admin url.
However, the problem I have is that the /admin scope (which sets the admin layout and provides the /admin/ url part) requires authentication, so I can’t display the admin’s login page for an unauthenticated admin. How would you solve that?
Note that I will have a SessionController for the website visitors as well, with different redirects on successful authentication, and different templates.