liquid_droppable.rb 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. # frozen_string_literal: true
  2. module LiquidDroppable
  3. class Drop < Liquid::Drop
  4. def initialize(object)
  5. @object = object
  6. end
  7. def to_s
  8. @object.to_s
  9. end
  10. def each
  11. (public_instance_methods - Drop.public_instance_methods).each { |name|
  12. yield [name, __send__(name)]
  13. }
  14. end
  15. def as_json
  16. return {} unless defined?(self.class::METHODS)
  17. self.class::METHODS.to_h { |m| [m, send(m).as_json] }
  18. end
  19. end
  20. class MatchDataDrop < Drop
  21. METHODS = %w[pre_match post_match names size]
  22. METHODS.each { |attr|
  23. define_method(attr) {
  24. @object.__send__(attr)
  25. }
  26. }
  27. def to_s
  28. @object[0]
  29. end
  30. def liquid_method_missing(method)
  31. @object[method]
  32. rescue IndexError
  33. nil
  34. end
  35. end
  36. class ::MatchData
  37. def to_liquid
  38. MatchDataDrop.new(self)
  39. end
  40. end
  41. require 'uri'
  42. class URIDrop < Drop
  43. METHODS = URI::Generic::COMPONENT
  44. METHODS.each { |attr|
  45. define_method(attr) {
  46. @object.__send__(attr)
  47. }
  48. }
  49. end
  50. class ::URI::Generic
  51. def to_liquid
  52. URIDrop.new(self)
  53. end
  54. end
  55. class ActiveRecordCollectionDrop < Drop
  56. include Enumerable
  57. def each(&block)
  58. @object.each(&block)
  59. end
  60. # required for variable indexing as array
  61. def [](i)
  62. case i
  63. when Integer
  64. @object[i]
  65. when 'size', 'first', 'last'
  66. __send__(i)
  67. end
  68. end
  69. # required for variable indexing as array
  70. def fetch(i, &block)
  71. @object.fetch(i, &block)
  72. end
  73. # compatibility with array; also required by the `size` filter
  74. def size
  75. @object.count
  76. end
  77. # compatibility with array
  78. def first
  79. @object.first
  80. end
  81. # compatibility with array
  82. def last
  83. @object.last
  84. end
  85. # This drop currently does not support the `slice` filter.
  86. end
  87. class ::ActiveRecord::Associations::CollectionProxy
  88. def to_liquid
  89. ActiveRecordCollectionDrop.new(self)
  90. end
  91. end
  92. end