I’ve been trying to figure out the best way to assign a layout to my liveviews loaded from the router. I have (at the moment) two distinct layout (in addition to the root, set with the plug put_root_layout) that i need to assign to two different list of liveviews.
I’ve tried to use put_layout in a specific pipeline that i then scope like this:
pipeline :live do
plug :put_layout, {MyAppWeb.LayoutView, :live}
end
pipeline :live_settings do
plug :put_layout, {MyAppWeb.LayoutView, :live_settings}
end
scope "/", MyAppWeb do
pipe_through [:main_pipeline, :app]
live "/", FirstLive
end
scope "/settings", MyAppWeb do
pipe_through [:main_pipeline, :settings]
live "/settings", SecondLive
end
I am aware of both options to either pass a layout option to the live macro, or declaring it like the phoenix generator does inside a quote with use Phoenix.LiveView, layout: {MyAppWeb.LayoutView, "live.html"} (note that i removed that one to instead do it in the router). I just find it clearer when used in the router through a pipeline.
I’ve found a few confusing things about this on the forum (like the now removed put_live_layout), so i’m not sure if doing the way i want just won’t work, or if i must have something on my side preventing it from working properly ?
Note: I’m on liveview 0.13.3. Haven’t seen any fix in the changelog on the newer versions, so i don’t think it’s a bug, unless i missed it.
That’s actually a typo, i’m calling the proper pipelines on the original code. Here’s the fixed version (can’t update the original post anymore), without the :live pipeline.
pipeline :live_settings do
plug :put_layout, {MyAppWeb.LayoutView, :live_settings}
end
scope "/", MyAppWeb do
pipe_through :main_pipeline
live "/", FirstLive
end
scope "/settings", MyAppWeb do
pipe_through [:main_pipeline, :live_settings]
live "/settings", SecondLive
end
That doesn’t change anything though. It’s still not working, the layout for the “/settings” scope isn’t being picked up. That’s a proper way to do it though, right ? Like it’s an issue on my part, and not something i shouldn’t try ?
Both template (:live and :live_settings) call <%= @inner_content %>. If i set either one of them directly with use Phoenix.LiveView, layout: {MyAppWeb.LayoutView, "live_settings.html"} (or the “live.html” version), it works flawlessly.
Yes, the main pipeline uses put_root_layout (and that one gets picked up properly).
I went to see if put_layout was actually setting the layout properly, and it seems to be the case (the :phoenix_layout property is set to the given layout depending on the scope properly). Despite this, i end up with the root layout being loaded, but not the other one.
After searching in LiveView’s code, i just found this, which i think is related to my problem, with what the live macro in the router is doing: Github LiveView relevant bit.
It looks like put_layout is called again, removing any previous assignment. Can anyone explain the reasoning behind this ?
We have changed layouts some point along the way so that:
root_layout is the layout shared between your LiveView and regular code
LiveView have their own layout which is specified inside the liveview (which is also diff/content tracked)
Therefore, we always disable the regular layout because otherwise you would end-up with three. Depending on what you want to achieve, I would rather change the root layout OR move this logic to inside the LiveView layout. I can’t see why you would need a third layout to wrap things around.
I’m not sure, but it seems like I have a very similar problem that I can’t resolve? I want to start phasing Material Design Bootstrap into our site, so I need to start changing parts of the site over (and leave all of the other areas styled as they are). My root.html.leex file in template/mdb_admin is being applied the same as my root.html.leex file in the template/admin folder as expected, but my live.html.leex in template/mdb_admin is not being applied.
So, my question is: Given the pipeline below, should I expect that my live.html.leex in mdb_admin should render instead of the one in layout? Also, is this an advisable way to separate the new portions of the site?
pipeline :mdbadmin do
plug :put_root_layout, {MyCompany.MdbAdminView, :root}
plug :put_layout, {MyCompany.MdbAdminView, :live}
end