How to convert old liveview app to new Phoenix version?


I am in the process of porting an old LiveView app to the newest version of Phoenix ( v1.6.5). Being new to the whole thing in general I was expecting to run mix web_interface --live --no-ecto and to the find a similar structure to what I had before:

│   ├───css
│   ├───js
│   └───static
│       └───images
│   ├───web_interface
│   └───web_interface_web
│       ├───channels
│       ├───live
│       ├───templates
│       │   └───layout
│       └───views

Instead I got:

│   ├───css
│   ├───js
│   └───vendor
│   └───web_interface
│       ├───controllers
│       ├───templates
│       │   ├───layout
│       │   └───page
│       └───views
    │   └───en
    │       └───LC_MESSAGES

Something is missing

Paying close attention you will now see I am missing a couple of important folders, namely, web_interface_web and the live folder.

So now I am understand the impression I either missed a huge milestone upgrade or that something is wrong with my mix command.


  • Why are these folders missing?
  • How can I port the project? What are the equivalent folders now?

It’s the new structure…

no more assets/static, since You don’t use webpack, and no more copy-webpack-plugin
→ just put manually in priv/static
no live folder, until You use mix
→ You can do it in a fresh Phoenix project, use mix, and You’ll have a live folder
no need to pass live to, it is not needed anymore
→ It’s the default now, mix help will show You the available options

This app is an umbrella app. This is why I used the previously mentioned command. Was I wrong to use it?
Will this new structure play nice with umbrella projects? (Do I need to do any additional tweaks?)

I don’t think it’s that different between an umbrella, and not an umbrella.

Mostly, it will change your mix file to point to the root of the umbrella, like this…

  def project do
      build_path: "../../_build",
      config_path: "../../config/config.exs",
      deps_path: "../../deps",
      lockfile: "../../mix.lock",

So if I understand correctly:

  • I create a normal phoenix app inside my umbrella via mix APP [--module MODULE] [--app APP]: mix — phx_new v1.6.5
  • Then I go inside the newly created folder and run mix

And then in theory, I get a Phoenix LiveView app.
There is one problem though:

mix phx.gen.html, phx.gen.json,, and phx.gen.context
expect a context module name, followed by singular and plural names
of the generated resource, ending with any number of attributes.
For example:

    mix phx.gen.html Accounts User users name:string
    mix phx.gen.json Accounts User users name:string
    mix Accounts User users name:string
    mix phx.gen.context Accounts User users name:string

The context serves as the API boundary for the given resource.
Multiple resources may belong to a context and a resource may be
split over distinct contexts (such as Accounts.User and Payments.User).

None of this was needed when I first started the old version of the project. I have a feeling there has been a major shift in paradigm here. I don’t understand what I am being asked.

Do you recommend any resources that can walk me through the new version?

Does anyone know if this course is updated enough that the Phoenix part is uppar with 1.6.5?

mix needs parameters… for example, as mentionned in the help.

mix Accounts User users name:string age:integer

It might not be scientific, but I always try to run commands in a demo application before I run in dev application.

The result is a live folder, with live_helpers.ex inside…

I’ll show the one generated for me.

defmodule MyappWeb.LiveHelpers do
  import Phoenix.LiveView
  import Phoenix.LiveView.Helpers

  alias Phoenix.LiveView.JS

  @doc """
  Renders a live component inside a modal.

  The rendered modal receives a `:return_to` option to properly update
  the URL when the modal is closed.

  ## Examples

      <.modal return_to={Routes.admin_user_index_path(@socket, :index)}>
          id={ || :new}
          return_to={Routes.admin_user_index_path(@socket, :index)}
          user: @user
  def modal(assigns) do
    assigns = assign_new(assigns, :return_to, fn -> nil end)

    <div id="modal" class="phx-modal fade-in" phx-remove={hide_modal()}>
        class="phx-modal-content fade-in-scale"
        phx-click-away={JS.dispatch("click", to: "#close")}
        phx-window-keydown={JS.dispatch("click", to: "#close")}
        <%= if @return_to do %>
          <%= live_patch "✖",
            to: @return_to,
            id: "close",
            class: "phx-modal-close",
            phx_click: hide_modal()
        <% else %>
         <a id="close" href="#" class="phx-modal-close" phx-click={hide_modal()}>✖</a>
        <% end %>

        <%= render_slot(@inner_block) %>

  defp hide_modal(js \\ %JS{}) do
    |> JS.hide(to: "#modal", transition: "fade-out")
    |> JS.hide(to: "#modal-content", transition: "fade-out-scale")

Just copy this file in live.

@kokolegorille I apologize if my question was not well formulated. I understand the command needs parameters and that a live folder is created.

What I don’t understand is the semantic meaning of the parameters and their implications in the new app. For example, does this mean my new live view app needs to be divided into models or subjects? in the previous version my app was not divided into this schema.

This is also why I was hoping if you knew any good courses for the new version. At this point, simply copy-pasting my old app would not do, as it won’t fit the new format.

this site may help you

1 Like