Releases: phlex-ruby/phlex
1.4.0
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
- Refactor by @joeldrapper in #488
- Add
paggio
to "Prior Art" section by @marcoroth in #491 - Omit
false
andnil
and empty strings when joining tokens by @joeldrapper in #495 - Phlex::SVG by @davekaro in #493
- Add SVG tag tests by @davekaro in #496
New Contributors
Full Changelog: 1.3.2...1.4.0
1.3.2
What's Changed
- Remove duplicate
onerror
event attribute by @joeldrapper in #475 - Support rendering view class from test by @joeldrapper in #476
- Add
<hgroup>
tag to the list of HTML elements by @jaredcwhite in #477 - Add YARD docs for HTML tags by @joeldrapper in #482
- Capture should use
yield_content
in order to capture return values by @joeldrapper in #484
Full Changelog: 1.3.1...1.3.2
1.3.1
What's Changed
- Fix unbuffered argument forwarding by @joeldrapper in #469
- Cache unbuffered class on the view class by @joeldrapper in #470
Full Changelog: 1.3.0...1.3.1
1.3.0
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
andPhlex::Table
abstractions have been removed — you’ll probably see new takes on these ideas in a new library soon.
What's Changed
- Redefine
call
and__attributes__
after first render by @joeldrapper in #459 - No false positives for
javascript:
link detection by @joeldrapper in #460 - Use
Concurrent::Map
for the attribute cache by @joeldrapper in #461 - Use
Concurrent::Map
for unbuffered cache by @joeldrapper in #462 - Avoid using
__callee__
by @joeldrapper in #463 - Support JRuby by @joeldrapper in #455
- Make
DeferredRender
not experimental by @joeldrapper in #464 - Remove experimental
collection
andtable
abstractions by @joeldrapper in #465 - Update Ruby version matrix by @joeldrapper in #466
Full Changelog: 1.2.1...1.3.0
1.2.1
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
- Detect string
href
attribute with javascript by @joeldrapper in #452 - Make
__vanish__
private by @joeldrapper in #453
Full Changelog: 1.2.0...1.2.1
1.2.0
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
- Update Gemfile removing
syntax_suggest
by @joeldrapper in #423 - Float should go through object formatters by @joeldrapper in #422
- Rename private methods by @joeldrapper in #424
- Define underscore prefixed tag methods by @joeldrapper in #425
- Remove experimental Turbo elements by @joeldrapper in #426
- Add experimental
DeferredRender
module by @joeldrapper in #427 - Use new
...
argument forwarding by @joeldrapper in #430 - Implement
DeferredRender
with newaround_content
hook by @joeldrapper in #431 - Revert "Implement
DeferredRender
with newaround_content
hook" by @joeldrapper in #432 - Add
Phlex::HTML#render
for rendering a component into a String by @marcoroth in #429 - Improve
DeferredRender
by @joeldrapper in #436 - Don't capture blocks when yielding by @joeldrapper in #437
- Add
clearwater
project to "Prior Art" section by @marcoroth in #439 - Detect block passed to
new
by @joeldrapper in #438 - Yield self when vanishing
DeferredRender
blocks by @joeldrapper in #441 - Ensure captures return original target by @joeldrapper in #444
- Fix ensured capture return values by @joeldrapper in #445
- Fix using keyword arguments in initializer by @willcosgrove in #447
- Unbuffered decorator by @joeldrapper in #448
- Update experimental warning by @joeldrapper in #450
- Warn when redefining underscored methods by @joeldrapper in #449
New Contributors
- @willcosgrove made their first contribution in #447
Full Changelog: 1.1.0...1.2.0
1.1.0
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
What's Changed
- Just render instance of class when given a class by @joeldrapper in #399
- Remove
rendered?
predicate by @joeldrapper in #401 - Make
render?
predicate private by @joeldrapper in #402 format_object
method by @joeldrapper in #398- Fix format object test by @joeldrapper in #405
- Disable Experimental Warnings configuration option by @joeldrapper in #406
- Support yielding from template by @joeldrapper in #407
Full Changelog: 1.0.0.rc2...1.0.0
1.0.0.rc2
Here’s another release candidate in advance of 1.0
later this week.
What's Changed
- Add then/else conditional token option by @bschrag620 in #392
- Switch from CGI to ERB::Util by @joeldrapper in #394
- Faster conditional tokens by @joeldrapper in #395
text
fallback toto_s
by @joeldrapper in #396
New Contributors
- @bschrag620 made their first contribution in #392
Full Changelog: 1.0.0.rc1...1.0.0.rc2
1.0.0.rc1
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 inphlex-markdown
- Remove
Phlex::Translation
— this is now available inphlex-translation
- Removed the compiler — this will be available in
phlex-compiler
- Removed
Phlex::Testing::Nokogiri
— this is now available inphlex-testing-nokogiri
- Removed
Phlex::Testing::Capybara
— this is now available inphlex-testing-capybara
- Removed
Phlex::Block
, all blocks are wrapped byyield_content
automatically which also ensures they execute in the right context - Added an
around_template
hook - Renamed
before_rendering_template
andafter_rendering_template
hooks tobefore_template
andafter_template
. You no longer need to prependPhlex::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