Skip to content

Releases: phlex-ruby/phlex

1.4.0

17 Feb 18:52
Compare
Choose a tag to compare

Highlights

The path and g tags have been removed from Phlex::HTML, but you can now use them from Phlex::SVG objects. You can also use Phlex::SVG directly from a Phlex::HTML template with the svg tag.

svg do |s|
  s.path
end

What's Changed

New Contributors

Full Changelog: 1.3.2...1.4.0

1.3.2

11 Feb 14:50
Compare
Choose a tag to compare

What's Changed

Full Changelog: 1.3.1...1.3.2

1.3.1

30 Jan 12:32
Compare
Choose a tag to compare

What's Changed

Full Changelog: 1.3.0...1.3.1

1.3.0

28 Jan 22:00
Compare
Choose a tag to compare

Highlights

  • Phlex is now thread-safe in TruffleRuby and JRuby. We now have full support for TruffleRuby v22.2+, JRuby v9.2+ and of course MRI v2.7+.
  • DeferredRender is no longer experimental.
  • Phlex::Collection and Phlex::Table abstractions have been removed — you’ll probably see new takes on these ideas in a new library soon.

What's Changed

Full Changelog: 1.2.1...1.3.0

1.2.1

25 Jan 13:07
Compare
Choose a tag to compare

Quick patch release to make the __vanish__ method used by DeferredRender private and improve the detection of unsafe user input. Previously, we would strip javascript from href attributes but only when the attribute was provided as a Symbol. Now, we check the href attribute as a Symbol or a String.

What's Changed

Full Changelog: 1.2.0...1.2.1

1.2.0

24 Jan 10:18
Compare
Choose a tag to compare

Highlights

Initialize a view instance with a block

You can now optionally pass a content block to .new instead of passing it to #render. You won't need to handle it in your initializer as it will continue to be passed to the template method. This means you no longer need to worry about the precedence of brace blocks vs do blocks but also means you can instantiate a view with its content and save it somewhere to be rendered later. It also means you can use argument forwarding to forward a method’s arguments to the initialiser of a different view.

For example, this Nav::Link view takes the arguments text and to::

class Nav::Link < Phlex::HTML
  def initialize(text, to:)
    @text, @to = text, to
  end

  def template
    li { a(href: @text) { @text } }
  end
end

We can define a public method on the Nav view that forwards its arguments to the Nav::Link initializer.

class Nav < Phlex::HTML
  def template(&)
    nav { ul(&) }
  end

  def link(...)
    render Link.new(...)
  end
end

Then we can use the Nav component like this.

render Nav do |n|
  n.link "Home", to: "/"
  n.link "About", to: "/about"
  n.link "Contact", to: "/contact"
end

[Experimental] DeferredRender pattern

The above technique won't help if you need to render slots more than once or out-of-order. In this case, we need to yield the block early and use public methods to capture all the slots before rendering the template. DeferredRender does just that. Here's how you could use it to build a tabs component where the tab labels are output before the tab contents.

class Tabs < Phlex::HTML
  # Create a data structure for each of our tabs
  Tab = Data.define(:name, :content)
  
  # Include DeferredRender for an early yield
  include DeferredRender
  
  def initialize
    # Create an empty list of tabs
    @tabs = []
  end
  
  # The template is rendered after yielding the block, so there's no content block to render.
  # Instead, the idea is to use the captured `@tabs` list, which we do in `#navigation` and `#contents`.
  def template
    div(class: "tabs") do
      navigation
      contents
    end
  end
  
  # This is called while yielding the block, so the caller can add tabs to our list
  def add_tab(name, &content)
    @tabs << Tab.new(name:, content:)
  end
  
  private
  
  # Both `navigation` and `contents` iterate through the list of tabs that we collected during the yield.
  def navigation
    ul(class: "tab-navigation") do
      @tabs.each do |tab|
        li { tab.name }
      end
    end
  end
  
  def contents
    div(class: "tab-contents") do
      @tabs.each do |tab|
        article(&tab.content)
      end
    end
  end
end

Underscored tag methods

Sometimes we need to override a tag method. If you’ve done this and need to get back to the original, you can now use _tagname.

Unbuffered decorator

You’ll probably never need to use this, but phlex-rails will use it for compatibility with ERB. The Unbuffered decorator can wrap a yielded view so that methods called on it return the captured result rather than immediately appending something to the output buffer. This means builder views (like the Nav example above) can behave like normal builders in ERB. We’ll share more details about this change in the next release of phlex-rails

Float now goes through object formatters

It's reasonable to want to customise the precision when outputting a float, so you can do the with format_object now.

def format_object(object)
  case object
  when Float
    object.round(2)
  else
    super
  end
end

Removed experimental Turbo views

@marcoroth’s new gem turbo-ruby uses Phlex to output Turbo elements, so we’ll probably switch to that in phlex-rails.

What's Changed

New Contributors

Full Changelog: 1.1.0...1.2.0

1.1.0

07 Jan 11:01
Compare
Choose a tag to compare

What's Changed

Always assign rendered_at_least_once when rendering a view by @joeldrapper in #408
When building attributes, Phlex checks whether the view class been rendered at least once before in order to determine whether it should cache the attributes. We only want to cache attributes on the first render in case some unique attribute causes the cache to grow infinitely. To keep track of whether a view class had been rendered before, it would use self.class.rendered_at_least_once ||= true after each render, but the ||= does an unnecessary check and it’s actually faster to just assign self.class.rendered_at_least_once = true without checking whether or not it's already true.

Call render? after setting view context by @joeldrapper in #412
The render? predicate — which is used as a guard against rendering — is now called after setting the view context, so you can now access helpers in your implementation of that method.

Render unsafe_raw with nil by @djfpaagman in #417
unsafe_raw has been updated to ignore nil values, so it no longer raises when you pass it nil. It also no longer accepts blocks.

Render data hash with string keys by @djfpaagman and @joeldrapper in #420
You can now use String keys in nested attributes. Previously, you could only use Symbol keys. String keys are not dasherized, so they're a good option if you need to use real underscores _ in your attributes.

Full Changelog: 1.0.0...1.1.0

1.0.0

08 Dec 12:42
Compare
Choose a tag to compare

What's Changed

Full Changelog: 1.0.0.rc2...1.0.0

1.0.0.rc2

27 Nov 10:16
Compare
Choose a tag to compare
1.0.0.rc2 Pre-release
Pre-release

Here’s another release candidate in advance of 1.0 later this week.

What's Changed

New Contributors

Full Changelog: 1.0.0.rc1...1.0.0.rc2

1.0.0.rc1

25 Nov 15:24
Compare
Choose a tag to compare
1.0.0.rc1 Pre-release
Pre-release

This is a release candidate for Phlex 1.0.

If you were using Phlex with rails, you'll need to install phlex-rails instead of phlex.

Notable changes

  • Remove Rails integration — this is now available in phlex-rails
  • Removed Phlex::Markdown — this is now available in phlex-markdown
  • Remove Phlex::Translation — this is now available in phlex-translation
  • Removed the compiler — this will be available in phlex-compiler
  • Removed Phlex::Testing::Nokogiri — this is now available in phlex-testing-nokogiri
  • Removed Phlex::Testing::Capybara — this is now available in phlex-testing-capybara
  • Removed Phlex::Block, all blocks are wrapped by yield_content automatically which also ensures they execute in the right context
  • Added an around_template hook
  • Renamed before_rendering_template and after_rendering_template hooks to before_template and after_template. You no longer need to prepend Phlex::Callbacks to use these either.
  • Added support for TruffleRuby
  • The comment helper method now accepts a block
  • Added a warning for experimental features like collections and tables

Full Changelog: 0.5.3...1.0.0.rc1