diff --git a/lib/liquid/standardfilters.rb b/lib/liquid/standardfilters.rb index 6855cd212..6728e57a6 100644 --- a/lib/liquid/standardfilters.rb +++ b/lib/liquid/standardfilters.rb @@ -421,13 +421,20 @@ def at_most(input, n) result.is_a?(BigDecimal) ? result.to_f : result end - def default(input, default_value = '') - if !input || input.respond_to?(:empty?) && input.empty? - Usage.increment("default_filter_received_false_value") if input == false # See https://github.com/Shopify/liquid/issues/1127 - default_value - else - input - end + # Set a default value when the input is nil, false or empty + # + # Example: + # {{ product.title | default: "No Title" }} + # + # Use `allow_false` when an input should only be tested against nil or empty and not false. + # + # Example: + # {{ product.title | default: "No Title", allow_false: true }} + # + def default(input, default_value = '', options = {}) + options = {} unless options.is_a?(Hash) + false_check = options['allow_false'] ? input.nil? : !input + false_check || (input.respond_to?(:empty?) && input.empty?) ? default_value : input end private diff --git a/test/integration/standard_filter_test.rb b/test/integration/standard_filter_test.rb index 5a6809fd0..705746346 100644 --- a/test/integration/standard_filter_test.rb +++ b/test/integration/standard_filter_test.rb @@ -685,6 +685,17 @@ def test_default assert_equal("bar", @filters.default(false, "bar")) assert_equal("bar", @filters.default([], "bar")) assert_equal("bar", @filters.default({}, "bar")) + assert_template_result('bar', "{{ false | default: 'bar' }}") + end + + def test_default_handle_false + assert_equal("foo", @filters.default("foo", "bar", "allow_false" => true)) + assert_equal("bar", @filters.default(nil, "bar", "allow_false" => true)) + assert_equal("bar", @filters.default("", "bar", "allow_false" => true)) + assert_equal(false, @filters.default(false, "bar", "allow_false" => true)) + assert_equal("bar", @filters.default([], "bar", "allow_false" => true)) + assert_equal("bar", @filters.default({}, "bar", "allow_false" => true)) + assert_template_result('false', "{{ false | default: 'bar', allow_false: true }}") end def test_cannot_access_private_methods