Liveview conventions, Why put liveview template in live folder?

I have recently started diving into phoenix_liveview and one question that keeps popping into my head which doesn’t make a whole lot of sense is. Why are liveview templates generally placed in the live folder? maybe is separation from regular templates?, but it doesn’t feel right. Shouldn’t all template go in the template folder as convention?

:wave:

I think it’s a matter of taste, some people consider collocation of the liveview logic with the template convenient. I don’t think there is any penalty for putting them into the templates folder.

I personally start with the template in the render function. Given the high cohesion between the template and the liveview/livecomponent, it makes sense to have everything in the same place. Once it grows too large to handle, I either make use of the collocation feature or break it even further apart in components.

3 Likes

Placing the template in the render function seems good to me. I was talking about placing the leex file in the live folder, that doesn’t feel right to me, I definitely understand that it can be a matter of taste, but I wanted to understand why place it there when template should be in the template folder by convention.

Not sure if there is any reason, but just wanted to say that I split my web code by features, so the controller, view and templates are in one directory. I think that it’s a better convention - we do that with contexts, so I welcome this approach by default for live views.

7 Likes

@stefanchrobot that actually sounds interesting, I take this approach for React Native, but I have not thought about this for a web framework, do you by any chance have an example of this? or resources I can look to see how this looks please. :pray:

1 Like

Here’s how I structured the sign-in/sign-out (session management) and registration features:

$stefan:mbp ~/dev/myapp/lib/myapp_web/accounts > tree
.
├── registration
│   ├── confirmation.html.eex
│   ├── new.html.eex
│   ├── registration_controller.ex
│   └── registration_view.ex
├── session
│   ├── confirmation.html.eex
│   ├── new.html.eex
│   ├── session_controller.ex
│   └── session_view.ex
└── user_auth.ex

Sample controller:

defmodule MyAppWeb.Accounts.RegistrationController do
  use MyAppWeb, :controller
  ...
end

To make this work, you just need to tell Phoenix where to lookup the templates (myapp_web.ex):

  def view do
    quote do
      use Phoenix.View,
        root: "lib/myapp_web",
        namespace: MyAppWeb

With this setup, putting live view templates into the same directory as the live view is perfectly consistent with the rest of the app.

8 Likes

I believe that the benefit to colocating templates is that you can omit the render function entirely, as it will infer the template to use.

1 Like

@stefanchrobot Thank you! looks interesting.

@mhanberg I know that was probably the intend, but it would of easily been done that it looks for it in the same name file inside the template folder. Also I like always using the render function, it removes ambiguity and it is often time 1 line of code if you are just rendering a view.

def render(assigns) do
   HomepageView.render("index.html", assigns)
end

I suspect it’s because LiveView templates are different under the hood. They contain extra functionality to handle the ‘only render the bit that’s changed’ logic, so are presumably processed by different code.