liquid_droppable.rb 1.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  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. end
  19. included do
  20. const_set :Drop,
  21. if Kernel.const_defined?(drop_name = "#{name}Drop")
  22. Kernel.const_get(drop_name)
  23. else
  24. Kernel.const_set(drop_name, Class.new(Drop))
  25. end
  26. end
  27. def to_liquid
  28. self.class::Drop.new(self)
  29. end
  30. class MatchDataDrop < Liquid::Drop
  31. def initialize(object)
  32. @object = object
  33. end
  34. %w[pre_match post_match names size].each { |attr|
  35. define_method(attr) {
  36. @object.__send__(attr)
  37. }
  38. }
  39. def to_s
  40. @object[0]
  41. end
  42. def before_method(method)
  43. @object[method]
  44. rescue IndexError
  45. nil
  46. end
  47. end
  48. class ::MatchData
  49. def to_liquid
  50. MatchDataDrop.new(self)
  51. end
  52. end
  53. require 'uri'
  54. class URIDrop < Drop
  55. URI::Generic::COMPONENT.each { |attr|
  56. define_method(attr) {
  57. @object.__send__(attr)
  58. }
  59. }
  60. end
  61. class ::URI::Generic
  62. def to_liquid
  63. URIDrop.new(self)
  64. end
  65. end
  66. end