Module: Liquid::StandardFilters
- Defined in:
- lib/liquid/standardfilters.rb
Defined Under Namespace
Classes: InputIterator
Constant Summary collapse
- HTML_ESCAPE =
{ '&' => '&', '>' => '>', '<' => '<', '"' => '"', "'" => ''', }.freeze
- HTML_ESCAPE_ONCE_REGEXP =
/["><']|&(?!([a-zA-Z]+|(#\d+));)/
- STRIP_HTML_BLOCKS =
Regexp.union( %r{<script.*?</script>}m, /<!--.*?-->/m, %r{<style.*?</style>}m, )
- STRIP_HTML_TAGS =
/<.*?>/m
Class Method Summary collapse
Instance Method Summary collapse
- #abs(input) ⇒ Object
- #append(input, string) ⇒ Object
- #at_least(input, n) ⇒ Object
- #at_most(input, n) ⇒ Object
- #base64_decode(input) ⇒ Object
- #base64_encode(input) ⇒ Object
- #base64_url_safe_decode(input) ⇒ Object
- #base64_url_safe_encode(input) ⇒ Object
- #capitalize(input) ⇒ Object
- #ceil(input) ⇒ Object
- #compact(input, property = nil) ⇒ Object
- #concat(input, array) ⇒ Object
-
#date(input, format) ⇒ Object
Reformat a date using Ruby’s core Time#strftime( string ) -> string.
- #default(input, default_value = '', options = {}) ⇒ Object
- #divided_by(input, operand) ⇒ Object
- #downcase(input) ⇒ Object
- #escape(input) ⇒ Object (also: #h)
- #escape_once(input) ⇒ Object
- #find(input, property, target_value = nil) ⇒ Object
- #find_index(input, property, target_value = nil) ⇒ Object
- #first(array) ⇒ Object
- #floor(input) ⇒ Object
- #has(input, property, target_value = nil) ⇒ Object
- #join(input, glue = ' ') ⇒ Object
- #last(array) ⇒ Object
- #lstrip(input) ⇒ Object
- #map(input, property) ⇒ Object
- #minus(input, operand) ⇒ Object
- #modulo(input, operand) ⇒ Object
- #newline_to_br(input) ⇒ Object
- #plus(input, operand) ⇒ Object
- #prepend(input, string) ⇒ Object
- #reject(input, property, target_value = nil) ⇒ Object
- #remove(input, string) ⇒ Object
- #remove_first(input, string) ⇒ Object
- #remove_last(input, string) ⇒ Object
- #replace(input, string, replacement = '') ⇒ Object
- #replace_first(input, string, replacement = '') ⇒ Object
- #replace_last(input, string, replacement) ⇒ Object
- #reverse(input) ⇒ Object
- #round(input, n = 0) ⇒ Object
- #rstrip(input) ⇒ Object
- #size(input) ⇒ Object
- #slice(input, offset, length = nil) ⇒ Object
- #sort(input, property = nil) ⇒ Object
- #sort_natural(input, property = nil) ⇒ Object
- #split(input, pattern) ⇒ Object
- #strip(input) ⇒ Object
- #strip_html(input) ⇒ Object
- #strip_newlines(input) ⇒ Object
- #sum(input, property = nil) ⇒ Object
- #times(input, operand) ⇒ Object
- #truncate(input, length = 50, truncate_string = "...") ⇒ Object
- #truncatewords(input, words = 15, truncate_string = "...") ⇒ Object
- #uniq(input, property = nil) ⇒ Object
- #upcase(input) ⇒ Object
- #url_decode(input) ⇒ Object
- #url_encode(input) ⇒ Object
- #where(input, property, target_value = nil) ⇒ Object
Class Method Details
.try_coerce_encoding(input, encoding:) ⇒ Object
33 34 35 36 37 38 39 40 41 42 |
# File 'lib/liquid/standardfilters.rb', line 33 def try_coerce_encoding(input, encoding:) original_encoding = input.encoding if input.encoding != encoding input.force_encoding(encoding) unless input.valid_encoding? input.force_encoding(original_encoding) end end input end |
Instance Method Details
#abs(input) ⇒ Object
784 785 786 787 |
# File 'lib/liquid/standardfilters.rb', line 784 def abs(input) result = Utils.to_number(input).abs result.is_a?(BigDecimal) ? result.to_f : result end |
#append(input, string) ⇒ Object
666 667 668 669 670 |
# File 'lib/liquid/standardfilters.rb', line 666 def append(input, string) input = Utils.to_s(input) string = Utils.to_s(string) input + string end |
#at_least(input, n) ⇒ Object
897 898 899 900 901 902 903 |
# File 'lib/liquid/standardfilters.rb', line 897 def at_least(input, n) min_value = Utils.to_number(n) result = Utils.to_number(input) result = min_value if min_value > result result.is_a?(BigDecimal) ? result.to_f : result end |
#at_most(input, n) ⇒ Object
912 913 914 915 916 917 918 |
# File 'lib/liquid/standardfilters.rb', line 912 def at_most(input, n) max_value = Utils.to_number(n) result = Utils.to_number(input) result = max_value if max_value < result result.is_a?(BigDecimal) ? result.to_f : result end |
#base64_decode(input) ⇒ Object
165 166 167 168 169 170 |
# File 'lib/liquid/standardfilters.rb', line 165 def base64_decode(input) input = Utils.to_s(input) StandardFilters.try_coerce_encoding(Base64.strict_decode64(input), encoding: input.encoding) rescue ::ArgumentError raise Liquid::ArgumentError, "invalid base64 provided to base64_decode" end |
#base64_encode(input) ⇒ Object
154 155 156 |
# File 'lib/liquid/standardfilters.rb', line 154 def base64_encode(input) Base64.strict_encode64(Utils.to_s(input)) end |
#base64_url_safe_decode(input) ⇒ Object
190 191 192 193 194 195 |
# File 'lib/liquid/standardfilters.rb', line 190 def base64_url_safe_decode(input) input = Utils.to_s(input) StandardFilters.try_coerce_encoding(Base64.urlsafe_decode64(input), encoding: input.encoding) rescue ::ArgumentError raise Liquid::ArgumentError, "invalid base64 provided to base64_url_safe_decode" end |
#base64_url_safe_encode(input) ⇒ Object
179 180 181 |
# File 'lib/liquid/standardfilters.rb', line 179 def base64_url_safe_encode(input) Base64.urlsafe_encode64(Utils.to_s(input)) end |
#capitalize(input) ⇒ Object
88 89 90 |
# File 'lib/liquid/standardfilters.rb', line 88 def capitalize(input) Utils.to_s(input).capitalize end |
#ceil(input) ⇒ Object
871 872 873 874 875 |
# File 'lib/liquid/standardfilters.rb', line 871 def ceil(input) Utils.to_number(input).ceil.to_i rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e. end |
#compact(input, property = nil) ⇒ Object
558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 |
# File 'lib/liquid/standardfilters.rb', line 558 def compact(input, property = nil) ary = InputIterator.new(input, context) if property.nil? ary.compact elsif ary.empty? # The next two cases assume a non-empty array. [] else ary.reject do |item| fetch_property(item, property).nil? rescue TypeError raise_property_error(property) rescue NoMethodError return nil unless item.respond_to?(:[]) raise end end end |
#concat(input, array) ⇒ Object
683 684 685 686 687 688 |
# File 'lib/liquid/standardfilters.rb', line 683 def concat(input, array) unless array.respond_to?(:to_ary) raise ArgumentError, "concat filter requires an array argument" end InputIterator.new(input, context).concat(array) end |
#date(input, format) ⇒ Object
Reformat a date using Ruby’s core Time#strftime( string ) -> string
%a - The abbreviated weekday name (``Sun'')
%A - The full weekday name (``Sunday'')
%b - The abbreviated month name (``Jan'')
%B - The full month name (``January'')
%c - The preferred local date and time representation
%d - Day of the month (01..31)
%H - Hour of the day, 24-hour clock (00..23)
%I - Hour of the day, 12-hour clock (01..12)
%j - Day of the year (001..366)
%m - Month of the year (01..12)
%M - Minute of the hour (00..59)
%p - Meridian indicator (``AM'' or ``PM'')
%s - Number of seconds since 1970-01-01 00:00:00 UTC.
%S - Second of the minute (00..60)
%U - Week number of the current year,
starting with the first Sunday as the first
day of the first week (00..53)
%W - Week number of the current year,
starting with the first Monday as the first
day of the first week (00..53)
%w - Day of the week (Sunday is 0, 0..6)
%x - Preferred representation for the date alone, no time
%X - Preferred representation for the time alone, no date
%y - Year without a century (00..99)
%Y - Year with century
%Z - Time zone name
%% - Literal ``%'' character
See also: http://www.ruby-doc.org/core/Time.html#method-i-strftime
746 747 748 749 750 751 752 753 |
# File 'lib/liquid/standardfilters.rb', line 746 def date(input, format) str_format = Utils.to_s(format) return input if str_format.empty? return input unless (date = Utils.to_date(input)) date.strftime(str_format) end |
#default(input, default_value = '', options = {}) ⇒ Object
932 933 934 935 936 |
# File 'lib/liquid/standardfilters.rb', line 932 def default(input, default_value = '', = {}) = {} unless .is_a?(Hash) false_check = ['allow_false'] ? input.nil? : !Liquid::Utils.to_liquid_value(input) false_check || (input.respond_to?(:empty?) && input.empty?) ? default_value : input end |
#divided_by(input, operand) ⇒ Object
829 830 831 832 833 |
# File 'lib/liquid/standardfilters.rb', line 829 def divided_by(input, operand) apply_operation(input, operand, :/) rescue ::ZeroDivisionError => e raise Liquid::ZeroDivisionError, e. end |
#downcase(input) ⇒ Object
66 67 68 |
# File 'lib/liquid/standardfilters.rb', line 66 def downcase(input) Utils.to_s(input).downcase end |
#escape(input) ⇒ Object Also known as: h
99 100 101 |
# File 'lib/liquid/standardfilters.rb', line 99 def escape(input) CGI.escapeHTML(Utils.to_s(input)) unless input.nil? end |
#escape_once(input) ⇒ Object
111 112 113 |
# File 'lib/liquid/standardfilters.rb', line 111 def escape_once(input) Utils.to_s(input).gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE) end |
#find(input, property, target_value = nil) ⇒ Object
474 475 476 |
# File 'lib/liquid/standardfilters.rb', line 474 def find(input, property, target_value = nil) filter_array(input, property, target_value) { |ary, &block| ary.find(&block) } end |
#find_index(input, property, target_value = nil) ⇒ Object
487 488 489 |
# File 'lib/liquid/standardfilters.rb', line 487 def find_index(input, property, target_value = nil) filter_array(input, property, target_value) { |ary, &block| ary.find_index(&block) } end |
#first(array) ⇒ Object
762 763 764 |
# File 'lib/liquid/standardfilters.rb', line 762 def first(array) array.first if array.respond_to?(:first) end |
#floor(input) ⇒ Object
884 885 886 887 888 |
# File 'lib/liquid/standardfilters.rb', line 884 def floor(input) Utils.to_number(input).floor.to_i rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e. end |
#has(input, property, target_value = nil) ⇒ Object
461 462 463 |
# File 'lib/liquid/standardfilters.rb', line 461 def has(input, property, target_value = nil) filter_array(input, property, target_value) { |ary, &block| ary.any?(&block) } end |
#join(input, glue = ' ') ⇒ Object
367 368 369 370 |
# File 'lib/liquid/standardfilters.rb', line 367 def join(input, glue = ' ') glue = Utils.to_s(glue) InputIterator.new(input, context).join(glue) end |
#last(array) ⇒ Object
773 774 775 |
# File 'lib/liquid/standardfilters.rb', line 773 def last(array) array.last if array.respond_to?(:last) end |
#lstrip(input) ⇒ Object
316 317 318 319 |
# File 'lib/liquid/standardfilters.rb', line 316 def lstrip(input) input = Utils.to_s(input) input.lstrip end |
#map(input, property) ⇒ Object
536 537 538 539 540 541 542 543 544 545 546 547 548 549 |
# File 'lib/liquid/standardfilters.rb', line 536 def map(input, property) InputIterator.new(input, context).map do |e| e = e.call if e.is_a?(Proc) if property == "to_liquid" e elsif e.respond_to?(:[]) r = fetch_property(e, property) r.is_a?(Proc) ? r.call : r end end rescue TypeError raise_property_error(property) end |
#minus(input, operand) ⇒ Object
807 808 809 |
# File 'lib/liquid/standardfilters.rb', line 807 def minus(input, operand) apply_operation(input, operand, :-) end |
#modulo(input, operand) ⇒ Object
842 843 844 845 846 |
# File 'lib/liquid/standardfilters.rb', line 842 def modulo(input, operand) apply_operation(input, operand, :%) rescue ::ZeroDivisionError => e raise Liquid::ZeroDivisionError, e. end |
#newline_to_br(input) ⇒ Object
710 711 712 713 |
# File 'lib/liquid/standardfilters.rb', line 710 def newline_to_br(input) input = Utils.to_s(input) input.gsub(/\r?\n/, "<br />\n") end |
#plus(input, operand) ⇒ Object
796 797 798 |
# File 'lib/liquid/standardfilters.rb', line 796 def plus(input, operand) apply_operation(input, operand, :+) end |
#prepend(input, string) ⇒ Object
697 698 699 700 701 |
# File 'lib/liquid/standardfilters.rb', line 697 def prepend(input, string) input = Utils.to_s(input) string = Utils.to_s(string) string + input end |
#reject(input, property, target_value = nil) ⇒ Object
448 449 450 |
# File 'lib/liquid/standardfilters.rb', line 448 def reject(input, property, target_value = nil) filter_array(input, property, target_value) { |ary, &block| ary.reject(&block) } end |
#remove(input, string) ⇒ Object
633 634 635 |
# File 'lib/liquid/standardfilters.rb', line 633 def remove(input, string) replace(input, string, '') end |
#remove_first(input, string) ⇒ Object
644 645 646 |
# File 'lib/liquid/standardfilters.rb', line 644 def remove_first(input, string) replace_first(input, string, '') end |
#remove_last(input, string) ⇒ Object
655 656 657 |
# File 'lib/liquid/standardfilters.rb', line 655 def remove_last(input, string) replace_last(input, string, '') end |
#replace(input, string, replacement = '') ⇒ Object
584 585 586 587 588 589 |
# File 'lib/liquid/standardfilters.rb', line 584 def replace(input, string, replacement = '') string = Utils.to_s(string) replacement = Utils.to_s(replacement) input = Utils.to_s(input) input.gsub(string, replacement) end |
#replace_first(input, string, replacement = '') ⇒ Object
598 599 600 601 602 603 |
# File 'lib/liquid/standardfilters.rb', line 598 def replace_first(input, string, replacement = '') string = Utils.to_s(string) replacement = Utils.to_s(replacement) input = Utils.to_s(input) input.sub(string, replacement) end |
#replace_last(input, string, replacement) ⇒ Object
612 613 614 615 616 617 618 619 620 621 622 623 624 |
# File 'lib/liquid/standardfilters.rb', line 612 def replace_last(input, string, replacement) input = Utils.to_s(input) string = Utils.to_s(string) replacement = Utils.to_s(replacement) start_index = input.rindex(string) return input unless start_index output = input.dup output[start_index, string.length] = replacement output end |
#reverse(input) ⇒ Object
524 525 526 527 |
# File 'lib/liquid/standardfilters.rb', line 524 def reverse(input) ary = InputIterator.new(input, context) ary.reverse end |
#round(input, n = 0) ⇒ Object
855 856 857 858 859 860 861 862 |
# File 'lib/liquid/standardfilters.rb', line 855 def round(input, n = 0) result = Utils.to_number(input).round(Utils.to_number(n)) result = result.to_f if result.is_a?(BigDecimal) result = result.to_i if n == 0 result rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e. end |
#rstrip(input) ⇒ Object
328 329 330 331 |
# File 'lib/liquid/standardfilters.rb', line 328 def rstrip(input) input = Utils.to_s(input) input.rstrip end |
#size(input) ⇒ Object
55 56 57 |
# File 'lib/liquid/standardfilters.rb', line 55 def size(input) input.respond_to?(:size) ? input.size : 0 end |
#slice(input, offset, length = nil) ⇒ Object
207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 |
# File 'lib/liquid/standardfilters.rb', line 207 def slice(input, offset, length = nil) offset = Utils.to_integer(offset) length = length ? Utils.to_integer(length) : 1 begin if input.is_a?(Array) input.slice(offset, length) || [] else Utils.to_s(input).slice(offset, length) || '' end rescue RangeError if I64_RANGE.cover?(length) && I64_RANGE.cover?(offset) raise # unexpected error end offset = offset.clamp(I64_RANGE) length = length.clamp(I64_RANGE) retry end end |
#sort(input, property = nil) ⇒ Object
379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 |
# File 'lib/liquid/standardfilters.rb', line 379 def sort(input, property = nil) ary = InputIterator.new(input, context) return [] if ary.empty? if property.nil? ary.sort do |a, b| nil_safe_compare(a, b) end elsif ary.all? { |el| el.respond_to?(:[]) } begin ary.sort { |a, b| nil_safe_compare(fetch_property(a, property), fetch_property(b, property)) } rescue TypeError raise_property_error(property) end end end |
#sort_natural(input, property = nil) ⇒ Object
408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 |
# File 'lib/liquid/standardfilters.rb', line 408 def sort_natural(input, property = nil) ary = InputIterator.new(input, context) return [] if ary.empty? if property.nil? ary.sort do |a, b| nil_safe_casecmp(a, b) end elsif ary.all? { |el| el.respond_to?(:[]) } begin ary.sort { |a, b| nil_safe_casecmp(fetch_property(a, property), fetch_property(b, property)) } rescue TypeError raise_property_error(property) end end end |
#split(input, pattern) ⇒ Object
291 292 293 294 295 |
# File 'lib/liquid/standardfilters.rb', line 291 def split(input, pattern) pattern = Utils.to_s(pattern) input = Utils.to_s(input) input.split(pattern) end |
#strip(input) ⇒ Object
304 305 306 307 |
# File 'lib/liquid/standardfilters.rb', line 304 def strip(input) input = Utils.to_s(input) input.strip end |
#strip_html(input) ⇒ Object
340 341 342 343 344 345 346 |
# File 'lib/liquid/standardfilters.rb', line 340 def strip_html(input) input = Utils.to_s(input) empty = '' result = input.gsub(STRIP_HTML_BLOCKS, empty) result.gsub!(STRIP_HTML_TAGS, empty) result end |
#strip_newlines(input) ⇒ Object
355 356 357 358 |
# File 'lib/liquid/standardfilters.rb', line 355 def strip_newlines(input) input = Utils.to_s(input) input.gsub(/\r?\n/, '') end |
#sum(input, property = nil) ⇒ Object
945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
# File 'lib/liquid/standardfilters.rb', line 945 def sum(input, property = nil) ary = InputIterator.new(input, context) return 0 if ary.empty? values_for_sum = ary.map do |item| if property.nil? item elsif item.respond_to?(:[]) fetch_property(item, property) else 0 end rescue TypeError raise_property_error(property) end result = InputIterator.new(values_for_sum, context).sum do |item| Utils.to_number(item) end result.is_a?(BigDecimal) ? result.to_f : result end |
#times(input, operand) ⇒ Object
818 819 820 |
# File 'lib/liquid/standardfilters.rb', line 818 def times(input, operand) apply_operation(input, operand, :*) end |
#truncate(input, length = 50, truncate_string = "...") ⇒ Object
237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/liquid/standardfilters.rb', line 237 def truncate(input, length = 50, truncate_string = "...") return if input.nil? input_str = Utils.to_s(input) length = Utils.to_integer(length) truncate_string_str = Utils.to_s(truncate_string) l = length - truncate_string_str.length l = 0 if l < 0 input_str.length > length ? input_str[0...l].concat(truncate_string_str) : input_str end |
#truncatewords(input, words = 15, truncate_string = "...") ⇒ Object
264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/liquid/standardfilters.rb', line 264 def truncatewords(input, words = 15, truncate_string = "...") return if input.nil? input = Utils.to_s(input) words = Utils.to_integer(words) words = 1 if words <= 0 wordlist = begin input.split(" ", words + 1) rescue RangeError # integer too big for String#split, but we can semantically assume no truncation is needed return input if words + 1 > MAX_I32 raise # unexpected error end return input if wordlist.length <= words wordlist.pop truncate_string = Utils.to_s(truncate_string) wordlist.join(" ").concat(truncate_string) end |
#uniq(input, property = nil) ⇒ Object
498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 |
# File 'lib/liquid/standardfilters.rb', line 498 def uniq(input, property = nil) ary = InputIterator.new(input, context) if property.nil? ary.uniq elsif ary.empty? # The next two cases assume a non-empty array. [] else ary.uniq do |item| fetch_property(item, property) rescue TypeError raise_property_error(property) rescue NoMethodError return nil unless item.respond_to?(:[]) raise end end end |
#upcase(input) ⇒ Object
77 78 79 |
# File 'lib/liquid/standardfilters.rb', line 77 def upcase(input) Utils.to_s(input).upcase end |
#url_decode(input) ⇒ Object
138 139 140 141 142 143 144 145 |
# File 'lib/liquid/standardfilters.rb', line 138 def url_decode(input) return if input.nil? result = CGI.unescape(Utils.to_s(input)) raise Liquid::ArgumentError, "invalid byte sequence in #{result.encoding}" unless result.valid_encoding? result end |
#url_encode(input) ⇒ Object
126 127 128 |
# File 'lib/liquid/standardfilters.rb', line 126 def url_encode(input) CGI.escape(Utils.to_s(input)) unless input.nil? end |
#where(input, property, target_value = nil) ⇒ Object
435 436 437 |
# File 'lib/liquid/standardfilters.rb', line 435 def where(input, property, target_value = nil) filter_array(input, property, target_value) { |ary, &block| ary.select(&block) } end |