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
- #first(array) ⇒ Object
- #floor(input) ⇒ 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
- #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
733 734 735 736 |
# File 'lib/liquid/standardfilters.rb', line 733 def abs(input) result = Utils.to_number(input).abs result.is_a?(BigDecimal) ? result.to_f : result end |
#append(input, string) ⇒ Object
621 622 623 |
# File 'lib/liquid/standardfilters.rb', line 621 def append(input, string) input.to_s + string.to_s end |
#at_least(input, n) ⇒ Object
846 847 848 849 850 851 852 |
# File 'lib/liquid/standardfilters.rb', line 846 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
861 862 863 864 865 866 867 |
# File 'lib/liquid/standardfilters.rb', line 861 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 = input.to_s 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(input.to_s) 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 = input.to_s 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(input.to_s) end |
#capitalize(input) ⇒ Object
88 89 90 |
# File 'lib/liquid/standardfilters.rb', line 88 def capitalize(input) input.to_s.capitalize end |
#ceil(input) ⇒ Object
820 821 822 823 824 |
# File 'lib/liquid/standardfilters.rb', line 820 def ceil(input) Utils.to_number(input).ceil.to_i rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e. end |
#compact(input, property = nil) ⇒ Object
519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 |
# File 'lib/liquid/standardfilters.rb', line 519 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| 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
636 637 638 639 640 641 |
# File 'lib/liquid/standardfilters.rb', line 636 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
696 697 698 699 700 701 702 |
# File 'lib/liquid/standardfilters.rb', line 696 def date(input, format) return input if format.to_s.empty? return input unless (date = Utils.to_date(input)) date.strftime(format.to_s) end |
#default(input, default_value = '', options = {}) ⇒ Object
881 882 883 884 885 |
# File 'lib/liquid/standardfilters.rb', line 881 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
778 779 780 781 782 |
# File 'lib/liquid/standardfilters.rb', line 778 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) input.to_s.downcase end |
#escape(input) ⇒ Object Also known as: h
99 100 101 |
# File 'lib/liquid/standardfilters.rb', line 99 def escape(input) CGI.escapeHTML(input.to_s) unless input.nil? end |
#escape_once(input) ⇒ Object
111 112 113 |
# File 'lib/liquid/standardfilters.rb', line 111 def escape_once(input) input.to_s.gsub(HTML_ESCAPE_ONCE_REGEXP, HTML_ESCAPE) end |
#first(array) ⇒ Object
711 712 713 |
# File 'lib/liquid/standardfilters.rb', line 711 def first(array) array.first if array.respond_to?(:first) end |
#floor(input) ⇒ Object
833 834 835 836 837 |
# File 'lib/liquid/standardfilters.rb', line 833 def floor(input) Utils.to_number(input).floor.to_i rescue ::FloatDomainError => e raise Liquid::FloatDomainError, e. end |
#join(input, glue = ' ') ⇒ Object
359 360 361 |
# File 'lib/liquid/standardfilters.rb', line 359 def join(input, glue = ' ') InputIterator.new(input, context).join(glue) end |
#last(array) ⇒ Object
722 723 724 |
# File 'lib/liquid/standardfilters.rb', line 722 def last(array) array.last if array.respond_to?(:last) end |
#lstrip(input) ⇒ Object
312 313 314 |
# File 'lib/liquid/standardfilters.rb', line 312 def lstrip(input) input.to_s.lstrip end |
#map(input, property) ⇒ Object
497 498 499 500 501 502 503 504 505 506 507 508 509 510 |
# File 'lib/liquid/standardfilters.rb', line 497 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 = e[property] r.is_a?(Proc) ? r.call : r end end rescue TypeError raise_property_error(property) end |
#minus(input, operand) ⇒ Object
756 757 758 |
# File 'lib/liquid/standardfilters.rb', line 756 def minus(input, operand) apply_operation(input, operand, :-) end |
#modulo(input, operand) ⇒ Object
791 792 793 794 795 |
# File 'lib/liquid/standardfilters.rb', line 791 def modulo(input, operand) apply_operation(input, operand, :%) rescue ::ZeroDivisionError => e raise Liquid::ZeroDivisionError, e. end |
#newline_to_br(input) ⇒ Object
661 662 663 |
# File 'lib/liquid/standardfilters.rb', line 661 def newline_to_br(input) input.to_s.gsub(/\r?\n/, "<br />\n") end |
#plus(input, operand) ⇒ Object
745 746 747 |
# File 'lib/liquid/standardfilters.rb', line 745 def plus(input, operand) apply_operation(input, operand, :+) end |
#prepend(input, string) ⇒ Object
650 651 652 |
# File 'lib/liquid/standardfilters.rb', line 650 def prepend(input, string) string.to_s + input.to_s end |
#remove(input, string) ⇒ Object
588 589 590 |
# File 'lib/liquid/standardfilters.rb', line 588 def remove(input, string) replace(input, string, '') end |
#remove_first(input, string) ⇒ Object
599 600 601 |
# File 'lib/liquid/standardfilters.rb', line 599 def remove_first(input, string) replace_first(input, string, '') end |
#remove_last(input, string) ⇒ Object
610 611 612 |
# File 'lib/liquid/standardfilters.rb', line 610 def remove_last(input, string) replace_last(input, string, '') end |
#replace(input, string, replacement = '') ⇒ Object
545 546 547 |
# File 'lib/liquid/standardfilters.rb', line 545 def replace(input, string, replacement = '') input.to_s.gsub(string.to_s, replacement.to_s) end |
#replace_first(input, string, replacement = '') ⇒ Object
556 557 558 |
# File 'lib/liquid/standardfilters.rb', line 556 def replace_first(input, string, replacement = '') input.to_s.sub(string.to_s, replacement.to_s) end |
#replace_last(input, string, replacement) ⇒ Object
567 568 569 570 571 572 573 574 575 576 577 578 579 |
# File 'lib/liquid/standardfilters.rb', line 567 def replace_last(input, string, replacement) input = input.to_s string = string.to_s replacement = replacement.to_s start_index = input.rindex(string) return input unless start_index output = input.dup output[start_index, string.length] = replacement output end |
#reverse(input) ⇒ Object
485 486 487 488 |
# File 'lib/liquid/standardfilters.rb', line 485 def reverse(input) ary = InputIterator.new(input, context) ary.reverse end |
#round(input, n = 0) ⇒ Object
804 805 806 807 808 809 810 811 |
# File 'lib/liquid/standardfilters.rb', line 804 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
323 324 325 |
# File 'lib/liquid/standardfilters.rb', line 323 def rstrip(input) input.to_s.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 input.to_s.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
370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 |
# File 'lib/liquid/standardfilters.rb', line 370 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(a[property], b[property]) } rescue TypeError raise_property_error(property) end end end |
#sort_natural(input, property = nil) ⇒ Object
399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 |
# File 'lib/liquid/standardfilters.rb', line 399 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(a[property], b[property]) } rescue TypeError raise_property_error(property) end end end |
#split(input, pattern) ⇒ Object
290 291 292 |
# File 'lib/liquid/standardfilters.rb', line 290 def split(input, pattern) input.to_s.split(pattern.to_s) end |
#strip(input) ⇒ Object
301 302 303 |
# File 'lib/liquid/standardfilters.rb', line 301 def strip(input) input.to_s.strip end |
#strip_html(input) ⇒ Object
334 335 336 337 338 339 |
# File 'lib/liquid/standardfilters.rb', line 334 def strip_html(input) empty = '' result = input.to_s.gsub(STRIP_HTML_BLOCKS, empty) result.gsub!(STRIP_HTML_TAGS, empty) result end |
#strip_newlines(input) ⇒ Object
348 349 350 |
# File 'lib/liquid/standardfilters.rb', line 348 def strip_newlines(input) input.to_s.gsub(/\r?\n/, '') end |
#sum(input, property = nil) ⇒ Object
894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 |
# File 'lib/liquid/standardfilters.rb', line 894 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?(:[]) 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
767 768 769 |
# File 'lib/liquid/standardfilters.rb', line 767 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 = input.to_s length = Utils.to_integer(length) truncate_string_str = truncate_string.to_s 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 |
# File 'lib/liquid/standardfilters.rb', line 264 def truncatewords(input, words = 15, truncate_string = "...") return if input.nil? input = input.to_s 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 wordlist.join(" ").concat(truncate_string.to_s) end |
#uniq(input, property = nil) ⇒ Object
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 |
# File 'lib/liquid/standardfilters.rb', line 459 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| 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) input.to_s.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(input.to_s) 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(input.to_s) unless input.nil? end |
#where(input, property, target_value = nil) ⇒ Object
426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 |
# File 'lib/liquid/standardfilters.rb', line 426 def where(input, property, target_value = nil) ary = InputIterator.new(input, context) if ary.empty? [] elsif target_value.nil? ary.select do |item| item[property] rescue TypeError raise_property_error(property) rescue NoMethodError return nil unless item.respond_to?(:[]) raise end else ary.select do |item| item[property] == target_value rescue TypeError raise_property_error(property) rescue NoMethodError return nil unless item.respond_to?(:[]) raise end end end |