Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support {...} interpolation in body #3514

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/single-file-samples/main.exs
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ defmodule Example.HomeLive do
<style>
* { font-size: 1.1em; }
</style>
<%= @inner_content %>
{@inner_content}
"""
end

def render(assigns) do
~H"""
<%= @count %>
{@count}
<button phx-click="inc">+</button>
<button phx-click="dec">-</button>
"""
Expand Down
2 changes: 1 addition & 1 deletion .github/single-file-samples/test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ defmodule Example.HomeLive do
<style>
* { font-size: 1.1em; }
</style>
<%= @inner_content %>
{@inner_content}
"""
end

Expand Down
4 changes: 2 additions & 2 deletions guides/client/bindings.md
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ for example:
def render(assigns) do
~H"""
<div id="thermostat" phx-window-keyup="update_temp">
Current temperature: <%= @temperature %>
Current temperature: {@temperature}
</div>
"""
end
Expand Down Expand Up @@ -384,7 +384,7 @@ For example:

```heex
<p class="alert" phx-click="lv:clear-flash" phx-value-key="info">
<%= Phoenix.Flash.get(@flash, :info) %>
{Phoenix.Flash.get(@flash, :info)}
</p>
```

Expand Down
4 changes: 2 additions & 2 deletions guides/client/js-interop.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ element from the server to draw the user's attention:

```heex
<div id={"item-#{item.id}"} class="item">
<%= item.title %>
{item.title}
</div>
```

Expand Down Expand Up @@ -110,7 +110,7 @@ attribute:

```heex
<div id={"item-#{item.id}"} class="item" data-highlight={JS.transition("highlight")}>
<%= item.title %>
{item.title}
</div>
```

Expand Down
4 changes: 2 additions & 2 deletions guides/introduction/welcome.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ defmodule MyAppWeb.ThermostatLive do

def render(assigns) do
~H"""
Current temperature: <%= @temperature %>°F
Current temperature: {@temperature}°F
<button phx-click="inc_temperature">+</button>
"""
end
Expand Down Expand Up @@ -235,7 +235,7 @@ function that receives an assigns map and returns a `~H` template. For example:
def weather_greeting(assigns) do
~H"""
<div title="My div" class={@class}>
<p>Hello <%= @name %></p>
<p>Hello {@name}</p>
<MyApp.Weather.city name="Kraków"/>
</div>
"""
Expand Down
34 changes: 17 additions & 17 deletions guides/server/assigns-eex.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
# Assigns and HEEx templates

All of the data in a LiveView is stored in the socket, which is a server
All of the data in a LiveView is stored in the socket, which is a server
side struct called `Phoenix.LiveView.Socket`. Your own data is stored
under the `assigns` key of said struct. The server data is never shared
with the client beyond what your template renders.

Phoenix template language is called HEEx (HTML+EEx). EEx is Embedded
Phoenix template language is called HEEx (HTML+EEx). EEx is Embedded
Elixir, an Elixir string template engine. Those templates
are either files with the `.heex` extension or they are created
directly in source files via the `~H` sigil. You can learn more about
Expand All @@ -27,7 +27,7 @@ static and dynamic parts of the template to the client. Imagine the
following template:

```heex
<h1><%= expand_title(@title) %></h1>
<h1>{expand_title(@title)}</h1>
```

It has two static parts, `<h1>` and `</h1>` and one dynamic part
Expand All @@ -46,7 +46,7 @@ Take this template:

```heex
<div id={"user_#{@user.id}"}>
<%= @user.name %>
{@user.name}
</div>
```

Expand All @@ -58,7 +58,7 @@ The change tracking also works when rendering other templates as
long as they are also `.heex` templates:

```heex
<%= render "child_template.html", assigns %>
{render("child_template.html", assigns)}
```

Or when using function components:
Expand All @@ -73,7 +73,7 @@ query in your template:

```heex
<%= for user <- Repo.all(User) do %>
<%= user.name %>
{user.name}
<% end %>
```

Expand Down Expand Up @@ -102,13 +102,13 @@ this in your HEEx templates:

```heex
<% some_var = @x + @y %>
<%= some_var %>
{some_var}
```

Instead, use a function:

```heex
<%= sum(@x, @y) %>
{sum(@x, @y)}
```

Similarly, **do not** define variables at the top of your `render` function
Expand All @@ -120,9 +120,9 @@ if either value changes, both must be re-rendered by LiveView.
title = assigns.title

~H"""
<h1><%= title %></h1>
<h1>{title}</h1>

<%= sum %>
{sum}
"""
end

Expand All @@ -141,9 +141,9 @@ The same functions can be used inside function components too:
assigns = assign(assigns, sum: assigns.x + assigns.y)

~H"""
<h1><%= @title %></h1>
<h1>{@title}</h1>

<%= @sum %>
{@sum}
"""
end

Expand All @@ -168,7 +168,7 @@ and instead use `@` for accessing specific keys. This also applies to
function components. Let's see some examples.

Sometimes you might want to pass all assigns from one function component to
another. For example, imagine you have a complex `card` component with
another. For example, imagine you have a complex `card` component with
header, content and footer section. You might refactor your component
into three smaller components internally:

Expand Down Expand Up @@ -209,7 +209,7 @@ def card(assigns) do
<div class="card">
<.card_header title={@title} class={@title_class} />
<.card_body>
<%= render_slot(@inner_block) %>
{render_slot(@inner_block)}
</.card_body>
<.card_footer on_close={@on_close} />
</div>
Expand All @@ -225,9 +225,9 @@ templates is acceptable:
def card(assigns) do
~H"""
<div class="card">
<%= card_header(assigns) %>
<%= card_body(assigns) %>
<%= card_footer(assigns) %>
{card_header(assigns)}
{card_body(assigns)}
{card_footer(assigns)}
</div>
"""
end
Expand Down
8 changes: 4 additions & 4 deletions guides/server/live-layouts.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ From Phoenix v1.7, your application is made of two layouts:
Overall, those layouts are found in `components/layouts` and are
embedded within `MyAppWeb.Layouts`.

All layouts must call `<%= @inner_content %>` to inject the
All layouts must call `{@inner_content}` to inject the
content rendered by the layout.

## Root layout
Expand Down Expand Up @@ -71,16 +71,16 @@ mount:
Then access `@page_title` in the root layout:

```heex
<title><%= @page_title %></title>
<title>{@page_title}</title>
```

You can also use the `Phoenix.Component.live_title/1` component to support
adding automatic prefix and suffix to the page title when rendered and
on subsequent updates:

```heex
<Phoenix.Component.live_title prefix="MyApp – ">
<%= assigns[:page_title] || "Welcome" %>
<Phoenix.Component.live_title default="Welcome" prefix="MyApp – ">
{assigns[:page_title]}
SteffenDE marked this conversation as resolved.
Show resolved Hide resolved
</Phoenix.Component.live_title>
```

Expand Down
26 changes: 9 additions & 17 deletions guides/server/uploads.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,35 +82,27 @@ Let's look at an annotated example:

<%!-- use phx-drop-target with the upload ref to enable file drag and drop --%>
<section phx-drop-target={@uploads.avatar.ref}>

<%!-- render each avatar entry --%>
<%= for entry <- @uploads.avatar.entries do %>
<article class="upload-entry">

<%!-- render each avatar entry --%>
<article :for={entry <- @uploads.avatar.entries} class="upload-entry">
<figure>
<.live_img_preview entry={entry} />
<figcaption><%= entry.client_name %></figcaption>
<figcaption>{entry.client_name}</figcaption>
</figure>

<%!-- entry.progress will update automatically for in-flight entries --%>
<progress value={entry.progress} max="100"> <%= entry.progress %>% </progress>
<progress value={entry.progress} max="100"> {entry.progress}% </progress>

<%!-- a regular click event whose handler will invoke Phoenix.LiveView.cancel_upload/3 --%>
<button type="button" phx-click="cancel-upload" phx-value-ref={entry.ref} aria-label="cancel">&times;</button>

<%!-- Phoenix.Component.upload_errors/2 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.avatar, entry) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>

<p :for={err <- upload_errors(@uploads.avatar, entry)} class="alert alert-danger">{error_to_string(err)}</p>
</article>
<% end %>

<%!-- Phoenix.Component.upload_errors/1 returns a list of error atoms --%>
<%= for err <- upload_errors(@uploads.avatar) do %>
<p class="alert alert-danger"><%= error_to_string(err) %></p>
<% end %>

<%!-- Phoenix.Component.upload_errors/1 returns a list of error atoms --%>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the EEx syntax is going away it seem odd to keep it around just for comment tags. Why not a {% %} style?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not going away though, it is not possible to do {if ... do}, {for ... do}, etc. (Not that people should reach for those given :if and :for exists.) We can't use {...} interpolation inside <script> and <style> either and for that <%= ... %> is the way to go.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The EEx syntax is not going away per se because it is still needed in some situations (such as inside script, style, and template, as escaping { in there would be a pain) but I agree we should probably consider introducing something specific for comments later on.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The <%!-- --%> comment syntax was inspired by Surface's {!-- --}. If we're moving to curly braces in the HTML, I'd vote we use the curly comments too.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 for {!-- --} style

<p :for={err <- upload_errors(@uploads.avatar)} class="alert alert-danger">
{error_to_string(err)}
</p>
</section>
```

Expand Down
Loading
Loading