Could use some direction on contributing to Phoenix… Specifically, is there a way to “test” the generators from my forked copy of master ? I’m seeing some weirdness around mix phx.new and mix phx.gen.auth ... and want to verify against master before writing up an issue and putting in a PR.
See this in the README
Appreciate your response to my question! I had my head stuck in CONTRIBUTING rather than in the README itself.
I am using Bandit with a Phoenix 1.7 rc0 app I upgraded
running using edeliver and Distillery, self hosted on a Vultr Bumblebee compatible GPU bare metal server
its fast, even local dev is FAST
especially local dev, 5 times faster makes a huge difference
Looks like 1.7.-rc.1 dropped yesterday. @chrismccord I’ve wondered for awhile, is there a typical cadence for rc releases and # of releases before a gm release?
Hey Guys,
Happy New Year.
I tried stopping myself from posting this without any substance, so I decided to browse the milestone page of Phoenix 1.7.
And lo and behold we have a progress indicator to follow:
Guys, Phoenix 1.7 RC 1 Dropped.
It’s happy new year indeed.
RC 2 is also available
Small question about rendering child templates with LiveView 0.18.11 and Phoenix 1.7-rc2:
My problem is that I have my LiveView templates split up into many smaller child templates and I put them together using the render/2 function like this:
# lib/app_web/live/home_live.ex
defmodule AppWeb.HomeLive do
use AppWeb, :live_view
def render(assigns), do: AppWeb.HomeView.render("index.html", assigns)
end
# lib/app_web/templates/home/index.html.heex
<div>
<h1>Hello World</h1>
<%= render "_child_template.html", assigns %>
</div>
# lib/app_web/templates/home/_child_template.html.heex
<div>
<h2>From the child!</h2>
</div>
Now it seems that the only options for rendering LiveView templates is either inside the LiveView using the ~H sigil or by colocating the template next to the LiveView. However, when colocating a template, I cannot use the render/2 function to render child templates.
Do I have to include the phoenix_view dependency in order to achieve the above with Phoenix 1.7 or is there another way to support child templates?
All the places you use render in can become calls to function components.
# lib/app_web/live/home_live.ex
defmodule AppWeb.HomeLive do
use AppWeb, :live_view
def render(assigns) do
AppWeb.HomeView.index(assigns)
# same as
# ~H"""
# <AppWeb.HomeView.index {assigns} />
# """
end
end
# lib/app_web/templates/home/index.html.heex
<div>
<h1>Hello World</h1>
<.child_template />
</div>
# lib/app_web/templates/home/child_template.html.heex
<div>
<h2>From the child!</h2>
</div>
Ah thank you! I actually found this in the docs, which explains it in more detail: Phoenix.Component — Phoenix LiveView v0.18.11
One more question then: Since Phoenix 1.7 will get rid of the HomeView views, how would I replace them in the render/1 function? Something like this maybe?
defmodule AppWeb.HomeLive do
use AppWeb, :live_view
def render(assigns), do: AppWeb.HomeHTML.render("show.html", assigns)
end
defmodule AppWeb.HomeHTML do
use AppWeb, :html
embed_templates "home/*"
end
This gives me the error: function AppWeb.HomeHTML.render/2 is undefined or private
Or do I have to define a Phoenix.Component that renders the show.html.heex so that I can use the child template function calls?
I tried colocating the template, but then I can’t use the child template function calls. So, this here won’t work for example:
# lib/app_web/live/home_live.ex
defmodule AppWeb.HomeLive do
use AppWeb, :live_view
end
# lib/app_web/live/home_live.html.heex
<div>
<h1>Hello World</h1>
<.child />
</div>
# lib/app_web/live/child.html.heex
<div>
<h2>From the child!</h2>
</div>
render (of views) is no longer a thing unless you’re manually including phoenix_view. Templates will become function components with embeds_templates. No more render("show.html", assigns), but <.show {assigns} /> or show(assigns).
You cannot colocate multiple templates and you never could in the past. Personally I’d love to get rid of them, because they’re just causing so much confusion. Explicitly requiring embed_templates in the LV module would’ve been so much cleaner, but it’s too late for that now. I’d suggest maintaining everything which is a subcomponent separate from the LV module and use co-located templates only as the single place of composition of subcomponents if at all. Since 1.7 I even tend to inline the render callback on LV modules most of the time. Also one-of pieces of markup are simple to be maintained as function (components) instead of in templates. If they’re so big that they need a template file I think it’s worth to move them to a separate module.
@LostKobrakai thanks for the insight!
I tried to visualize the old and new ways of rendering HTML from the LiveView or Controller through render, colocation, or calling a View. Does this below make sense or did I forget something?
This totally misses the fact that colocated templates for LV used Phoenix.View pre 1.7 – you just never saw it (which is one of my problems with the feature).
LVs can be their own view module instead of having an external one. That internal functionality uses the exact same functionality as an external view module would, just limited to a single template with an inferred but known name. That applies to both pre 1.7 phoenix as well as post 1.7 phoenix.
The thing that changed is that Phoenix.View(render/2) and all APIs based on it were replaced with plain function calls of template_name/1, which happen to align with what heex function components call internally.
Thanks! I updated the drawing a bit to incorporate your feedback.
Also, to sum up the findings regarding rendering child templates:
From Phoenix 1.7 on, one has to wrap the template and its child templates in a Phoenix.Component and then call it as functions, right?
So, this is the old way:
# lib/app_web/live/home_live.ex
defmodule AppWeb.HomeLive do
use AppWeb, :live_view
def render(assigns), do: AppWeb.HomeView.render("show.html", assigns)
end
# lib/app_web/views/home_view.ex
defmodule AppWeb.HomeView do
use AppWeb, :view
end
# lib/app_web/templates/home/show.html.heex
<div>
<h1>Hello World</h1>
<%= render "_child.html", assigns %>
</div>
# lib/app_web/templates/home/_child.html.heex
<div>
<h2>From the child!</h2>
</div>
And this would be the new way:
# lib/app_web/live/home_live.ex
defmodule AppWeb.HomeLive do
use AppWeb, :live_view
def render(assigns) do
~H"""
<AppWeb.HomeHTML.show />
"""
end
end
# lib/app_web/live/home_html.ex
defmodule AppWeb.HomeHTML do
use AppWeb, :html
embed_templates "home/*"
end
# lib/app_web/live/home/show.html.heex
<div>
<h1>Hello World</h1>
<.child />
</div>
# lib/app_web/live/home/child.html.heex
<div>
<h2>From the child!</h2>
</div>
I am really looking forward to this one. I am using htmx 14 these days and they have a nice essay on locality of behavior.
Can you expand on your approach? A mini tutorial in a post would be awesome.
I think the graph can be simplified in two parts. There are two questions:
- How to render templates
- How to define templates
Rendering goes like this for controllers and LVs:
-
Controller → Phoenix.Template.render → FooBarHTML.action/1 which returns HEEx (in particular, the Phoenix.LiveView.Rendered struct)
-
LiveView →
FooBarLive.render→ returns HEEx
Now to define templates:
- Either define a function that uses the ~H sigil
- Use embed_templates
This is important because you can totally use the ~H sigil and define FooBarHTML.action/1 manually. So IMO the graph should have two completely separate parts that meet in the same place only at the end (they meet on the HEEx) or two separate diagrams.
I am working on it.
Yes, I’d also like to suggest the option to have a --no-tailwind option. I work on a lot of projects that require the use of OSI approved licenses and tailwind isn’t open source, and on bigger corporate teams is likely to require their costly Team License.
I understand that as things stand with 1.7, it’s only the core_components that uses tailwind out of the box and that I could replace the styling of the components in there to use another framework. That’s not a big deal and it’s likely that the community will share examples of these core components being styled for other frameworks.
My main concern is if this “tailwind by default” approach will appear in other parts of generator outputs, mainly because of the license incompatibility that might cause when it comes to open source projects using Phoenix























