Adjusting the Layouts
The Phoenix Generator created two layouts for us:
layouts/root.html.heex
- The Root Layout is always used. It's a good idea to keep this minimal, since it will apply to all pages.layouts/app.html.heex
- The application layout is used for all LiveViews.
The Root Layout
The Root Layout generates with a simple header. This header includes login, register, and user settings links. While this is a good start, we will add a branding section to the left side of the header.
Replace everything between the body
tags with:
<div class="flex justify-between px-4 mt-2">
<.link navigate={~p"/"} class="font-black">Elixir Mud</.link>
<ul class="relative z-10 flex items-center gap-4 sm:px-6 lg:px-8 justify-end">
<li :if={@current_player} class="text-[0.8125rem] leading-6 text-zinc-900">
{@current_player.email}
</li>
<li :if={@current_player}>
<.link
href={~p"/players/settings"}
class="text-[0.8rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700"
>
Settings
</.link>
</li>
<li :if={@current_player}>
<.link
href={~p"/players/log_out"}
method="delete"
class="text-[0.8rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700"
>
Log out
</.link>
</li>
<li :if={!@current_player}>
<.link
href={~p"/players/register"}
class="text-[0.8rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700"
>
Register
</.link>
</li>
<li :if={!@current_player}>
<.link
href={~p"/players/log_in"}
class="text-[0.8rem] leading-6 text-zinc-900 font-semibold hover:text-zinc-700"
>
Log in
</.link>
</li>
</ul>
</div>
apps/elixir_mud_web/lib/elixir_mud_web/components/layouts/root.html.heex
The Application Layout
The application layout contains some Phoenix links. We can remove those. For now replace the contents with:
<header class="px-4 sm:px-6 lg:px-8">
<div class="flex items-center justify-between border-b border-zinc-100 py-3 text-sm">
<div class="flex items-center gap-4">
</div>
</div>
</header>
<main class="px-4 py-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl">
<.flash_group flash={@flash} />
{@inner_content}
</div>
</main>
apps/elixir_mud_web/lib/elixir_mud_web/components/layouts/app.html.heex
The Empty Layout
We will use the Application Layout specifically for pages inside the main web application, such as character creation and the web client. Lets implement an Empty Layout that we can use for registration, login, etc. This will keep those pages clean.
Create a new file in the layouts folder called empty.html.heex
:
<main class="px-4 py-20 sm:px-6 lg:px-8">
<div class="mx-auto max-w-2xl">
<.flash_group flash={@flash} />
{@inner_content}
</div>
</main>
Modifying The Routes
Now it's time to modify routes to use the new Empty Layout. We simply need to add layout: {LayoutModule, :name}
to the LiveSession
. In our case that will be layout: {ElixirMudWeb.Layouts, :empty}
.
First, there is a LiveSession
that contains routes for registration and login:
scope "/", ElixirMudWeb do
pipe_through [:browser, :redirect_if_player_is_authenticated]
live_session :redirect_if_player_is_authenticated,
layout: {ElixirMudWeb.Layouts, :empty},
on_mount: [{ElixirMudWeb.PlayerAuth, :redirect_if_player_is_authenticated}] do
live "/players/register", PlayerRegistrationLive, :new
live "/players/log_in", PlayerLoginLive, :new
live "/players/reset_password", PlayerForgotPasswordLive, :new
live "/players/reset_password/:token", PlayerResetPasswordLive, :edit
end
post "/players/log_in", PlayerSessionController, :create
end
apps/elixir_mud_web/lib/elixir_mud_web/router.ex
Second, the LiveSession
for player settings:
scope "/", ElixirMudWeb do
pipe_through [:browser, :require_authenticated_player]
live_session :require_authenticated_player,
layout: {ElixirMudWeb.Layouts, :empty},
on_mount: [{ElixirMudWeb.PlayerAuth, :ensure_authenticated}] do
live "/players/settings", PlayerSettingsLive, :edit
live "/players/settings/confirm_email/:token", PlayerSettingsLive, :confirm_email
end
end
apps/elixir_mud_web/lib/elixir_mud_web/router.ex
Lastly, the LiveSession
for confirmation:
scope "/", ElixirMudWeb do
pipe_through [:browser]
delete "/players/log_out", PlayerSessionController, :delete
live_session :current_player,
layout: {ElixirMudWeb.Layouts, :empty},
on_mount: [{ElixirMudWeb.PlayerAuth, :mount_current_player}] do
live "/players/confirm/:token", PlayerConfirmationLive, :edit
live "/players/confirm", PlayerConfirmationInstructionsLive, :new
end
end
apps/elixir_mud_web/lib/elixir_mud_web/router.ex
Checking Tests
If we run mix test
, we should see that all tests are passing. Nothing we changed is effecting any current test cases.