thojanssens1

thojanssens1

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!

Showing Posts 1 to 5

idi527

idi527

:waving_hand:

You can have “scoped” controllers like

defmodule YourAppWeb.Admin.QuestionController do
end

this would make phoenix use lib/quiz_maker_web/view/admin/question_view.ex and look in lib/quiz_maker_web/templates/admin/ for the templates.

jeremyjh

jeremyjh

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.

thojanssens1

thojanssens1 OP

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?

scope "/admin", MyAppWebWeb, as: :admin do
  pipe_through [:browser, :authenticate_user, :admin_pages]
  resources "/questions", Admin.QuestionController
  resources "/users", Admin.UserController, except: [:edit, :update]
  resources "/sessions", Admin.SessionController, only: [:new, :create, :delete]
end

Note that I will have a SessionController for the website visitors as well, with different redirects on successful authentication, and different templates.

thojanssens1

thojanssens1 OP

I just remembered about nested scope and it solved my problem about th admin login page it seems:

scope "/admin", MyAppWeb, as: :admin do
  pipe_through [:browser, :admin_pages]
  resources "/sessions", Admin.SessionController, only: [:new, :create]

  scope "/" do
    pipe_through [:authenticate_user]
    resources "/users", Admin.UserController, except: [:edit, :update]
    resources "/sessions", Admin.SessionController, only: [:delete]
  end
end

:slight_smile:

— All posts loaded —

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
FlyingNoodle
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews