mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-13 16:00:41 -07:00
Compare commits
4
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bf1419b8ac | ||
|
|
5718c4cee2 | ||
|
|
b0dbc62696 | ||
|
|
03aafa974c |
+3
-1
@@ -29,6 +29,8 @@
|
||||
|
||||
## Releasing
|
||||
|
||||
* Bump the version in `lib/liquid/version.rb` and merge it on `main`
|
||||
* Bump the version in `lib/liquid/version.rb`
|
||||
* Update the `History.md` file
|
||||
* Open a PR like [this one](https://github.com/Shopify/liquid/pull/1894) and merge it to `main`
|
||||
* Create a new release using the [GitHub UI](https://github.com/Shopify/liquid/releases/new)
|
||||
|
||||
|
||||
@@ -20,6 +20,10 @@ group :benchmark, :test do
|
||||
end
|
||||
end
|
||||
|
||||
group :development do
|
||||
gem "webrick"
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem 'rubocop', '~> 1.61.0'
|
||||
gem 'rubocop-shopify', '~> 2.12.0', require: false
|
||||
|
||||
+50
-2
@@ -1,12 +1,60 @@
|
||||
# Liquid Change Log
|
||||
|
||||
## 5.6.0 (unreleased)
|
||||
## 5.8.0 (unreleased)
|
||||
|
||||
## 5.7.1 2025-01-23
|
||||
|
||||
* Fix the `find` and `find_index`filters to return `nil` when filtering empty arrays
|
||||
* Fix the `has` filter to return `false` when filtering empty arrays
|
||||
|
||||
## 5.7.0 2025-01-16
|
||||
|
||||
### Features
|
||||
|
||||
* Add `find`, `find_index`, `has`, and `reject` filters to arrays
|
||||
* Compatibility with Ruby 3.4
|
||||
|
||||
## 5.6.4 2025-01-14
|
||||
|
||||
### Fixes
|
||||
* Add a default `string_scanner` to avoid errors with `Liquid::VariableLookup.parse("foo.bar")` [Ian Ker-Seymer]
|
||||
|
||||
## 5.6.3 2025-01-13
|
||||
* Remove `lru_redux` dependency [Michael Go]
|
||||
|
||||
## 5.6.2 2025-01-13
|
||||
|
||||
### Fixes
|
||||
* Preserve the old behavior of requiring floats to start with a digit [Michael Go]
|
||||
|
||||
## 5.6.1 2025-01-13
|
||||
|
||||
### Performance improvements
|
||||
* Faster Expression parser / Tokenizer with StringScanner [Michael Go]
|
||||
|
||||
## 5.6.0 2024-12-19
|
||||
|
||||
### Architectural changes
|
||||
* Added new `Environment` class to manage configuration and state that was previously stored in `Template` [Ian Ker-Seymer]
|
||||
* Moved tag registration from `Template` to `Environment` [Ian Ker-Seymer]
|
||||
* Removed `StrainerFactory` in favor of `Environment`-based strainer creation [Ian Ker-Seymer]
|
||||
* Consolidated standard tags into a new `Tags` module with `STANDARD_TAGS` constant [Ian Ker-Seymer]
|
||||
|
||||
### Performance improvements
|
||||
* Optimized `Lexer` with a new `Lexer2` implementation using jump tables for faster tokenization, requires Ruby 3.4 [Ian Ker-Seymer]
|
||||
* Improved variable rendering with specialized handling for different types [Michael Go]
|
||||
* Reduced array allocations by using frozen empty constants [Michael Go]
|
||||
|
||||
### API changes
|
||||
* Deprecated several `Template` class methods in favor of `Environment` methods [Ian Ker-Seymer]
|
||||
* Added deprecation warnings system [Ian Ker-Seymer]
|
||||
* Changed how filters and tags are registered to use Environment [Ian Ker-Seymer]
|
||||
|
||||
### Fixes
|
||||
* Fixed table row handling of break interrupts [Alex Coco]
|
||||
* Improved variable output handling for arrays [Ian Ker-Seymer]
|
||||
* Fix Tokenizer to handle null source value (#1873) [Bahar Pourazar]
|
||||
|
||||
|
||||
## 5.5.0 2024-03-21
|
||||
|
||||
Please reference the GitHub release for more information.
|
||||
|
||||
@@ -459,7 +459,7 @@ module Liquid
|
||||
# @liquid_syntax array | some: string, string
|
||||
# @liquid_return [boolean]
|
||||
def has(input, property, target_value = nil)
|
||||
filter_array(input, property, target_value) { |ary, &block| ary.any?(&block) }
|
||||
filter_array(input, property, target_value, false) { |ary, &block| ary.any?(&block) }
|
||||
end
|
||||
|
||||
# @liquid_public_docs
|
||||
@@ -472,7 +472,7 @@ module Liquid
|
||||
# @liquid_syntax array | find: string, string
|
||||
# @liquid_return [untyped]
|
||||
def find(input, property, target_value = nil)
|
||||
filter_array(input, property, target_value) { |ary, &block| ary.find(&block) }
|
||||
filter_array(input, property, target_value, nil) { |ary, &block| ary.find(&block) }
|
||||
end
|
||||
|
||||
# @liquid_public_docs
|
||||
@@ -485,7 +485,7 @@ module Liquid
|
||||
# @liquid_syntax array | find_index: string, string
|
||||
# @liquid_return [number]
|
||||
def find_index(input, property, target_value = nil)
|
||||
filter_array(input, property, target_value) { |ary, &block| ary.find_index(&block) }
|
||||
filter_array(input, property, target_value, nil) { |ary, &block| ary.find_index(&block) }
|
||||
end
|
||||
|
||||
# @liquid_public_docs
|
||||
@@ -969,10 +969,10 @@ module Liquid
|
||||
|
||||
attr_reader :context
|
||||
|
||||
def filter_array(input, property, target_value, &block)
|
||||
def filter_array(input, property, target_value, default_value = [], &block)
|
||||
ary = InputIterator.new(input, context)
|
||||
|
||||
return [] if ary.empty?
|
||||
return default_value if ary.empty?
|
||||
|
||||
block.call(ary) do |item|
|
||||
if target_value.nil?
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Liquid
|
||||
VERSION = "5.6.5"
|
||||
VERSION = "5.7.1"
|
||||
end
|
||||
|
||||
@@ -157,6 +157,18 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_equal([], @filters.slice(input, -(1 << 63), 6))
|
||||
end
|
||||
|
||||
def test_find_on_empty_array
|
||||
assert_nil(@filters.find([], 'foo', 'bar'))
|
||||
end
|
||||
|
||||
def test_find_index_on_empty_array
|
||||
assert_nil(@filters.find_index([], 'foo', 'bar'))
|
||||
end
|
||||
|
||||
def test_has_on_empty_array
|
||||
refute(@filters.has([], 'foo', 'bar'))
|
||||
end
|
||||
|
||||
def test_truncate
|
||||
assert_equal('1234...', @filters.truncate('1234567890', 7))
|
||||
assert_equal('1234567890', @filters.truncate('1234567890', 20))
|
||||
@@ -976,6 +988,18 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_template_result(expected_output, "{{ array | has: 'ok', true }}", { "array" => array })
|
||||
end
|
||||
|
||||
def test_has_with_empty_arrays
|
||||
template = <<~LIQUID
|
||||
{%- assign has_product = products | has: 'title.content', 'Not found' -%}
|
||||
{%- unless has_product -%}
|
||||
Product not found.
|
||||
{%- endunless -%}
|
||||
LIQUID
|
||||
expected_output = "Product not found."
|
||||
|
||||
assert_template_result(expected_output, template, { "products" => [] })
|
||||
end
|
||||
|
||||
def test_has_with_false_value
|
||||
array = [
|
||||
{ "handle" => "alpha", "ok" => true },
|
||||
@@ -1042,6 +1066,18 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_template_result(expected_output, template, { "products" => TestDeepEnumerable.new })
|
||||
end
|
||||
|
||||
def test_find_with_empty_arrays
|
||||
template = <<~LIQUID
|
||||
{%- assign product = products | find: 'title.content', 'Not found' -%}
|
||||
{%- unless product -%}
|
||||
Product not found.
|
||||
{%- endunless -%}
|
||||
LIQUID
|
||||
expected_output = "Product not found."
|
||||
|
||||
assert_template_result(expected_output, template, { "products" => [] })
|
||||
end
|
||||
|
||||
def test_find_index_with_value
|
||||
products = [
|
||||
{ "title" => "Pro goggles", "price" => 1299 },
|
||||
@@ -1070,6 +1106,18 @@ class StandardFiltersTest < Minitest::Test
|
||||
assert_template_result(expected_output, template, { "products" => TestDeepEnumerable.new })
|
||||
end
|
||||
|
||||
def test_find_index_with_empty_arrays
|
||||
template = <<~LIQUID
|
||||
{%- assign index = products | find_index: 'title.content', 'Not found' -%}
|
||||
{%- unless index -%}
|
||||
Index not found.
|
||||
{%- endunless -%}
|
||||
LIQUID
|
||||
expected_output = "Index not found."
|
||||
|
||||
assert_template_result(expected_output, template, { "products" => [] })
|
||||
end
|
||||
|
||||
def test_where
|
||||
array = [
|
||||
{ "handle" => "alpha", "ok" => true },
|
||||
|
||||
Reference in New Issue
Block a user