New layouts in Phoenix

I have problems converting an app to new layout structure, with root and app layout templates.
Previously I configured the layout in controller, so when page was rendered, the template @view_module had a view of current page rendered. Now with layout configured in plug the view is LayoutView.

So I cannot script includes depending on page rendered like:
<%= render_existing @view_module, “css.” <> @view_template, assigns %>
case current view_module is not of page rendered.

I can move everything in app.html template, but this misses the purpose of root template.
What I am doing wrong?

3 Likes

Thank you I was just debugging my upgrade and was running into this without realizing it.

Looks like the only ref to the view left in the conn is in the private :phoenix_view

Have an idea.

Make a view helper function inside of of the LayoutView pass it the conn and extract :phoenix_view from the private and pass that in place of the @view_module and same for :phoenix_template in place of the @view_template

Thanks, will try to do that. I really do not quite get the logic behind new layout scheme.

Its because of the flash logic mostly, if you look at the diff between the app vs the live thats the only real diff

I’m in the process of extracting out the private from the conn, not the most elegant solution but should work.

So not tested but something like this.

# my_app_web/views/layout_view.ex

  def render_existing_nested(
        %{
          :phoenix_template => phoenix_template,
          :phoenix_view => phoenix_view
        },
        tag,
        assigns
      ) do
    render_existing(phoenix_view, tag <> phoenix_template, assigns)
  end

And in my root.html.leex

  <%= render_existing_nested @conn.private, "script.", assigns %>

I just gave this a try in my own project and it seems to work, but I have not tried a liveview example.
I assume the privates maybe different in which case an update to the pattern matching is all that’s really needed.

1 Like

Have to test the solution. The thing is that in rendered script and css templates (depending on page/template) and insert subtemplates with partials. Like scripts for datatables.

Previously I had a control over what in included, now with inner content I lost track, what is inner content.

But I am a novice in Phoenix :slight_smile:

So if you look in the conn’s private that information is still there, they just don’t create an assign var for them. Its up to you to pluck it out.

Ok will test tomorrow. I left PC for today.

I ended using:

<%= render_existing @conn.private.phoenix_view, “css.” <> @conn.private.phoenix_template, assigns %>

Probably not the best idea using private vars, but it works.

2 Likes

Meh what ever works :man_shrugging:

So found the correct way to address this. https://morphic.pro/posts/upgrading-phoenix-1-5s-render-existing

No need to write that helper function after all.

2 Likes

That website seems to be down and I could only access it via archive.org.

I ran into that issue today after doing the move to root.html.eex, so for posterity the solution is to simply use view_module/1 - so view_module(@conn) - instead of accessing @view_module directly.

2 Likes