mirror of
https://github.com/Shopify/liquid.git
synced 2026-09-30 23:55:12 -07:00
Compare commits
15
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3af10eb58c | ||
|
|
f1846d63a3 | ||
|
|
af3f8612bf | ||
|
|
6f8722a6d3 | ||
|
|
81f44e36be | ||
|
|
c9ec8f4635 | ||
|
|
3fb467f069 | ||
|
|
992e15a173 | ||
|
|
0bb6539dce | ||
|
|
1fdc577246 | ||
|
|
74245cd396 | ||
|
|
86605016e1 | ||
|
|
6981305736 | ||
|
|
6d3c5ef3d3 | ||
|
|
150ddf4c3b |
@@ -1,2 +0,0 @@
|
||||
enabled:
|
||||
- cla
|
||||
@@ -0,0 +1,22 @@
|
||||
name: Contributor License Agreement (CLA)
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, synchronize]
|
||||
issue_comment:
|
||||
types: [created]
|
||||
|
||||
jobs:
|
||||
cla:
|
||||
runs-on: ubuntu-latest
|
||||
if: |
|
||||
(github.event.issue.pull_request
|
||||
&& !github.event.issue.pull_request.merged_at
|
||||
&& contains(github.event.comment.body, 'signed')
|
||||
)
|
||||
|| (github.event.pull_request && !github.event.pull_request.merged)
|
||||
steps:
|
||||
- uses: Shopify/shopify-cla-action@v1
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
cla-token: ${{ secrets.CLA_TOKEN }}
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
# Liquid Change Log
|
||||
|
||||
## 5.4.0 (unreleased)
|
||||
## 5.4.0 2022-07-29
|
||||
|
||||
### Breaking Changes
|
||||
* Drop support for end-of-life Ruby versions (2.5 and 2.6) (#1578) [Andy Waite]
|
||||
@@ -11,6 +11,7 @@
|
||||
### Fixes
|
||||
* `PartialCache` now shares snippet cache with subcontexts by default (#1553) [Chris AtLee]
|
||||
* Hash registers no longer leak into subcontexts as static registers (#1564) [Chris AtLee]
|
||||
* Fix `ParseTreeVisitor` for `with` variable expressions in `Render` tag (#1596) [CP Clermont]
|
||||
|
||||
### Changed
|
||||
* Liquid::Context#registers now always returns a Liquid::Registers object, though supports the most used Hash functions for compatibility (#1553)
|
||||
|
||||
@@ -15,12 +15,19 @@ module Liquid
|
||||
end
|
||||
|
||||
# @liquid_public_docs
|
||||
# @liquid_name forloop.length
|
||||
# @liquid_name length
|
||||
# @liquid_summary
|
||||
# The total number of iterations in the loop.
|
||||
# @liquid_return [number]
|
||||
attr_reader :length
|
||||
|
||||
# @liquid_public_docs
|
||||
# @liquid_name parentloop
|
||||
# @liquid_summary
|
||||
# The parent `forloop` object.
|
||||
# @liquid_description
|
||||
# If the current `for` loop isn't nested inside another `for` loop, then `nil` is returned.
|
||||
# @liquid_return [forloop]
|
||||
attr_reader :parentloop
|
||||
|
||||
def name
|
||||
|
||||
@@ -358,7 +358,11 @@ module Liquid
|
||||
# @liquid_type filter
|
||||
# @liquid_category array
|
||||
# @liquid_summary
|
||||
# Sorts the items in an array in case-insensitive alphabetical, or numerical, order.
|
||||
# Sorts the items in an array in case-insensitive alphabetical order.
|
||||
# @liquid_description
|
||||
# > Caution:
|
||||
# > You shouldn't use the `sort_natural` filter to sort numerical values. When comparing items an array, each item is converted to a
|
||||
# > string, so sorting on numerical values can lead to unexpected results.
|
||||
# @liquid_syntax array | sort_natural
|
||||
# @liquid_return [array[untyped]]
|
||||
def sort_natural(input, property = nil)
|
||||
|
||||
@@ -14,6 +14,10 @@ module Liquid
|
||||
strainer_from_cache(filters).new(context)
|
||||
end
|
||||
|
||||
def global_filter_names
|
||||
GlobalCache.filter_method_names
|
||||
end
|
||||
|
||||
GlobalCache = Class.new(StrainerTemplate)
|
||||
|
||||
private
|
||||
|
||||
@@ -24,11 +24,11 @@ module Liquid
|
||||
|
||||
include(filter)
|
||||
|
||||
filter_methods.merge(filter.public_instance_methods.map(&:to_s))
|
||||
filter_methods.merge(filter.public_instance_methods)
|
||||
end
|
||||
|
||||
def invokable?(method)
|
||||
filter_methods.include?(method.to_s)
|
||||
filter_methods.include?(method.to_sym)
|
||||
end
|
||||
|
||||
def inherited(subclass)
|
||||
@@ -36,6 +36,13 @@ module Liquid
|
||||
subclass.instance_variable_set(:@filter_methods, @filter_methods.dup)
|
||||
end
|
||||
|
||||
# Assuming the filter name is a string is deprecated, explicitly
|
||||
# cast to_s or to_sym for compatibility with liquid 6, where it is
|
||||
# planned to return as a symbol.
|
||||
def filter_method_names
|
||||
filter_methods.map(&:to_s).to_a
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filter_methods
|
||||
@@ -44,6 +51,7 @@ module Liquid
|
||||
end
|
||||
|
||||
def invoke(method, *args)
|
||||
method = method.to_sym
|
||||
if self.class.invokable?(method)
|
||||
send(method, *args)
|
||||
elsif @context.strict_filters
|
||||
|
||||
@@ -31,7 +31,7 @@ module Liquid
|
||||
|
||||
disable_tags "include"
|
||||
|
||||
attr_reader :template_name_expr, :attributes
|
||||
attr_reader :template_name_expr, :variable_name_expr, :attributes
|
||||
|
||||
def initialize(tag_name, markup, options)
|
||||
super
|
||||
@@ -99,6 +99,7 @@ module Liquid
|
||||
def children
|
||||
[
|
||||
@node.template_name_expr,
|
||||
@node.variable_name_expr,
|
||||
] + @node.attributes.values
|
||||
end
|
||||
end
|
||||
|
||||
@@ -15,7 +15,7 @@ module Liquid
|
||||
# @liquid_syntax
|
||||
# {% unless condition %}
|
||||
# expression
|
||||
# {% endif %}
|
||||
# {% endunless %}
|
||||
# @liquid_syntax_keyword condition The condition to evaluate.
|
||||
# @liquid_syntax_keyword expression The expression to render unless the condition is met.
|
||||
class Unless < If
|
||||
|
||||
+11
-3
@@ -18,7 +18,7 @@ module Liquid
|
||||
JustTagAttributes = /\A#{TagAttributes}\z/o
|
||||
MarkupWithQuotedFragment = /(#{QuotedFragment})(.*)/om
|
||||
|
||||
attr_accessor :filters, :name, :line_number
|
||||
attr_accessor :name, :line_number
|
||||
attr_reader :parse_context
|
||||
alias_method :options, :parse_context
|
||||
|
||||
@@ -52,7 +52,7 @@ module Liquid
|
||||
filters = Regexp.last_match(1).scan(FilterParser)
|
||||
filters.each do |f|
|
||||
next unless f =~ /\w+/
|
||||
filtername = Regexp.last_match(0)
|
||||
filtername = Regexp.last_match(0).to_sym
|
||||
filterargs = f.scan(FilterArgsRegex).flatten
|
||||
@filters << parse_filter_expressions(filtername, filterargs)
|
||||
end
|
||||
@@ -67,13 +67,21 @@ module Liquid
|
||||
|
||||
@name = parse_context.parse_expression(p.expression)
|
||||
while p.consume?(:pipe)
|
||||
filtername = p.consume(:id)
|
||||
filtername = p.consume(:id).to_sym
|
||||
filterargs = p.consume?(:colon) ? parse_filterargs(p) : []
|
||||
@filters << parse_filter_expressions(filtername, filterargs)
|
||||
end
|
||||
p.consume(:end_of_string)
|
||||
end
|
||||
|
||||
# Assuming the filter name is a string is deprecated, explicitly
|
||||
# cast to_s or to_sym for compatibility with liquid 6, where it is
|
||||
# planned to return as a symbol.
|
||||
def filters
|
||||
# Remove to_s in liquid 6.0
|
||||
@filters.map { |key, *args| [key.to_s, *args].freeze }.freeze
|
||||
end
|
||||
|
||||
def parse_filterargs(p)
|
||||
# first argument
|
||||
filterargs = [p.argument]
|
||||
|
||||
@@ -32,6 +32,10 @@ module Liquid
|
||||
end
|
||||
end
|
||||
|
||||
def lookup_command?(lookup_index)
|
||||
@command_flags & (1 << lookup_index) != 0
|
||||
end
|
||||
|
||||
def evaluate(context)
|
||||
name = context.evaluate(@name)
|
||||
object = context.find_variable(name)
|
||||
@@ -55,7 +59,7 @@ module Liquid
|
||||
# Some special cases. If the part wasn't in square brackets and
|
||||
# no key with the same name was found we interpret following calls
|
||||
# as commands and call them on the current object
|
||||
elsif @command_flags & (1 << i) != 0 && object.respond_to?(key)
|
||||
elsif lookup_command?(i) && object.respond_to?(key)
|
||||
object = object.send(key).to_liquid
|
||||
|
||||
# No key was present with the desired value and it wasn't one of the directly supported
|
||||
|
||||
@@ -2,5 +2,5 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
module Liquid
|
||||
VERSION = "5.4.0.alpha"
|
||||
VERSION = "5.4.0"
|
||||
end
|
||||
|
||||
@@ -236,6 +236,20 @@ class ParseTreeVisitorTest < Minitest::Test
|
||||
)
|
||||
end
|
||||
|
||||
def test_render_with
|
||||
assert_equal(
|
||||
["test"],
|
||||
visit(%({% render "hai" with test %}))
|
||||
)
|
||||
end
|
||||
|
||||
def test_render_for
|
||||
assert_equal(
|
||||
["test"],
|
||||
visit(%({% render "hai" for test %}))
|
||||
)
|
||||
end
|
||||
|
||||
def test_preserve_tree_structure
|
||||
assert_equal(
|
||||
[[nil, [
|
||||
|
||||
@@ -60,7 +60,7 @@ class StrainerTemplateUnitTest < Minitest::Test
|
||||
with_global_filter do
|
||||
strainer = Context.new.strainer
|
||||
strainer.class.add_filter(PublicMethodOverrideFilter)
|
||||
assert(strainer.class.send(:filter_methods).include?('public_filter'))
|
||||
assert(strainer.class.filter_method_names.include?('public_filter'))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user