liquid_droppable.rb 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. # Include this mix-in to make a class droppable to Liquid, and adjust
  2. # its behavior in Liquid by implementing its dedicated Drop class
  3. # named with a "Drop" suffix.
  4. module LiquidDroppable
  5. extend ActiveSupport::Concern
  6. class Drop < Liquid::Drop
  7. def initialize(object)
  8. @object = object
  9. end
  10. def to_s
  11. @object.to_s
  12. end
  13. def each
  14. (public_instance_methods - Drop.public_instance_methods).each { |name|
  15. yield [name, __send__(name)]
  16. }
  17. end
  18. def as_json
  19. return {} unless defined?(self.class::METHODS)
  20. Hash[self.class::METHODS.map { |m| [m, send(m).as_json]}]
  21. end
  22. end
  23. included do
  24. const_set :Drop,
  25. if Kernel.const_defined?(drop_name = "#{name}Drop")
  26. Kernel.const_get(drop_name)
  27. else
  28. Kernel.const_set(drop_name, Class.new(Drop))
  29. end
  30. end
  31. def to_liquid
  32. self.class::Drop.new(self)
  33. end
  34. class MatchDataDrop < Drop
  35. METHODS = %w[pre_match post_match names size]
  36. METHODS.each { |attr|
  37. define_method(attr) {
  38. @object.__send__(attr)
  39. }
  40. }
  41. def to_s
  42. @object[0]
  43. end
  44. def before_method(method)
  45. @object[method]
  46. rescue IndexError
  47. nil
  48. end
  49. end
  50. class ::MatchData
  51. def to_liquid
  52. MatchDataDrop.new(self)
  53. end
  54. end
  55. require 'uri'
  56. class URIDrop < Drop
  57. METHODS = URI::Generic::COMPONENT
  58. METHODS.each { |attr|
  59. define_method(attr) {
  60. @object.__send__(attr)
  61. }
  62. }
  63. end
  64. class ::URI::Generic
  65. def to_liquid
  66. URIDrop.new(self)
  67. end
  68. end
  69. class ::ActiveRecord::Associations::CollectionProxy
  70. def to_liquid
  71. self.to_a.to_liquid
  72. end
  73. end
  74. end