Skip to content

2.1.0.rc1

Pre-release
Pre-release
Compare
Choose a tag to compare
@joeldrapper joeldrapper released this 28 Feb 16:30
· 34 commits to main since this release

Summary

This is the first release candidate for v2.1 which uses a completely different architecture for interoperating with ERB templates from ActionView and ViewComponent. It does this by sharing a buffer rather than trying to patch all the different interactions.

This release is a minor breaking change which means it could break your code, so be careful when upgrading. If you rely on using slot-style components from ERB, you need to make sure you’re not using <%= tags when calling slot methods on the component. <%= should be used only for the render or for rendering values. See in this example, we do not use <%= for the t.column call.

<%= render Table.new(@people) do |t| %>
  <% t.column("Name") do |person| %>
    <%= person.name %>
  <% end %>

  <% t.column("Age") do |person| %>
    <%= person.age %>
  <% end %>
<% end %>

For UI Kit maintainers, it’s probably a good idea to make your slot methods return nil in case a user does pass them to <%= output tags. If we didn’t return nil from column in this example, the <%= ERB output tags would output the to_s of the @columns array.

def column(header, &content)
  @columns << { header:, content: }
  nil # <-- return nil
end

If your components are builder-style (e.g. not yielding early), you can usually just depend on the fact that most of Phlex own methods return nil.

Impersonating a Rails builder

If you need to use Phlex to impersonate a Rails builder object where builder methods return HTML-safe strings instead of pushing output to a buffer, you will need to wrap each builder method in a capture. I can only think of one library that might need to do this for API compatibility.

class Nav < Phlex::HTML
  def view_template(&)
    nav(class: "special-nav", &)
  end

  def item(href, &)
    capture do
      a(class: "special-nav-item", href:, &)
    end
  end

  def divider
    capture do
      span(class: "special-nav-divider")
    end
  end
end

Using this component inside Phlex would be strange because you would have to use raw, to render the captured strings.

render Nav do |n|
  raw n.item("/") { "Home" }
end

PRs

Full Changelog: 2.0.2...2.1.0.rc1