ryanzidago
How can I set a specific layout for a specific LiveView?
I have the following route:
scope "/:locale", MyAppWeb do
pipe_through :browser
live "/", LandingPageLive, :home
# some other routes
end
And this in MyAppWeb:
def live_view do
quote do
use Phoenix.LiveView,
layout: {MyAppWeb.Layouts, :app}
on_mount MyAppWeb.SetLocale
unquote(html_helpers())
end
end
This means that by default all LiveViews have the app layout.
How can I make it so that the LandingPageLive does not have the app layout (which contains a sidebar)?
Looking at the documentation, I see here that there are two ways to override the default layout:
- live_session which I do not have
- :layout option when mounting the LiveView.
Since I don’t have a live_session in my router, I’m going for the second option using {MyAppWeb.Layouts, :landing_page}:
defmodule MyAppWeb.LandingPageLive do
use MyAppWeb, :live_view
use Gettext, backend: MyAppWeb.Gettext
@impl LiveView
def mount(params, _session, socket) do
socket = assign(socket, layout: {MyAppWeb.Layouts, :landing_page})
{:ok, socket}
end
@impl LiveView
def render(assigns) do
~H"""
Welcome!
"""
end
end
And I have a the following directory structure:
lib/my_app_web/
├── components
│ ├── core_components.ex
│ ├── layouts
│ │ ├── app.html.heex
│ │ ├── landing_page.html.heex
│ │ └── root.html.heex
│ ├── layouts.ex
│ └── sidebar.ex
├── live
│ ├── landing_page_live.ex
However, I get this error:
invalid value for reserved key :layout in Phoenix.Template.render/4 assigns.
:layout accepts a tuple of the form {LayoutModule, "template.extension"},
got: {ClipboardWeb.Layouts, :landing_page}
Looks like I need to pass a string:
defmodule MyAppWeb.LandingPageLive do
use MyAppWeb, :live_view
use Gettext, backend: MyAppWeb.Gettext
@impl LiveView
def mount(params, _session, socket) do
socket = assign(socket, layout: {MyAppWeb.Layouts, "landing_page.html"})
{:ok, socket}
end
@impl LiveView
def render(assigns) do
~H"""
Welcome!
"""
end
end
Not enough:
no "landing_page.html" html template defined for ClipboardWeb.Layouts (the module exists but does not define landing_page.html/1 nor render/2
My MyAppWeb.Layouts looks like so:
defmodule MyAppWeb.Layouts do
@moduledoc """
This module holds different layouts used by your application.
See the `layouts` directory for all templates available.
The "root" layout is a skeleton rendered as part of the
application router. The "app" layout is set as the default
layout on both `use MyAppWeb, :controller` and
`use MyAppWeb, :live_view`.
"""
use MyAppWeb, :html
alias MyAppWeb.Sidebar
embed_templates "layouts/*"
end
Thus I assume that it embeds all templates under the lib/my_app_web/components/layouts/.
What’s the expectation here?
Trending in Questions
Other Trending Topics
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #ai
- #elixirconf-us
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #elixirconf-eu
- #metaprogramming
- #hex











Showing Posts 1 to 4- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
ryanzidago
Decided to hack around by conditionally rendering the sidebar in the app layout based on the
@sidebar_enabledvariable that I set on a server hook:Which I then call in
MyAppWeb:Though feels more like a hack than a solution.
rhcarvalho
The return value from
mountcan also set the layout::temporary_assigns- a keyword list of assigns that are temporary and must be reset to their value after every render. Note that once the value is reset, it won’t be re-rendered again until it is explicitly assigned:layout- the optional layout to be used by the LiveView. Setting this option will override any layout previously set viaPhoenix.LiveView.Router.live_session/2or onuse Phoenix.LiveViewLostKobrakai
This is wrong. You don’t assign the layout as an assign on the socket, but it’s an option on the return tuple of mount.
ryanzidago
Ah yeah completely on my, I now see clearly how it’s written in the documentation:
Many thanks both of you @rhcarvalho @LostKobrakai !