123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132 |
- # frozen_string_literal: true
- # Include this mix-in to make a class droppable to Liquid, and adjust
- # its behavior in Liquid by implementing its dedicated Drop class
- # named with a "Drop" suffix.
- module LiquidDroppable
- extend ActiveSupport::Concern
- class Drop < Liquid::Drop
- def initialize(object)
- @object = object
- end
- def to_s
- @object.to_s
- end
- def each
- (public_instance_methods - Drop.public_instance_methods).each { |name|
- yield [name, __send__(name)]
- }
- end
- def as_json
- return {} unless defined?(self.class::METHODS)
- Hash[self.class::METHODS.map { |m| [m, send(m).as_json]}]
- end
- end
- included do
- const_set :Drop,
- if Kernel.const_defined?(drop_name = "#{name}Drop")
- Kernel.const_get(drop_name)
- else
- Kernel.const_set(drop_name, Class.new(Drop))
- end
- end
- def to_liquid
- self.class::Drop.new(self)
- end
- class MatchDataDrop < Drop
- METHODS = %w[pre_match post_match names size]
- METHODS.each { |attr|
- define_method(attr) {
- @object.__send__(attr)
- }
- }
- def to_s
- @object[0]
- end
- def liquid_method_missing(method)
- @object[method]
- rescue IndexError
- nil
- end
- end
- class ::MatchData
- def to_liquid
- MatchDataDrop.new(self)
- end
- end
- require 'uri'
- class URIDrop < Drop
- METHODS = URI::Generic::COMPONENT
- METHODS.each { |attr|
- define_method(attr) {
- @object.__send__(attr)
- }
- }
- end
- class ::URI::Generic
- def to_liquid
- URIDrop.new(self)
- end
- end
- class ActiveRecordCollectionDrop < Drop
- include Enumerable
- def each(&block)
- @object.each(&block)
- end
- # required for variable indexing as array
- def [](i)
- case i
- when Integer
- @object[i]
- when 'size', 'first', 'last'
- __send__(i)
- end
- end
- # required for variable indexing as array
- def fetch(i, &block)
- @object.fetch(i, &block)
- end
- # compatibility with array; also required by the `size` filter
- def size
- @object.count
- end
- # compatibility with array
- def first
- @object.first
- end
- # compatibility with array
- def last
- @object.last
- end
- # This drop currently does not support the `slice` filter.
- end
- class ::ActiveRecord::Associations::CollectionProxy
- def to_liquid
- ActiveRecordCollectionDrop.new(self)
- end
- end
- end
|