Sha256: e6e49c5611484ad3e2f8c79731553937270e6fdc45e142751daf6a5847d83799

Contents?: true

Size: 1.79 KB

Versions: 7

Compression:

Stored size: 1.79 KB

Contents

require 'set'

module Liquid

  # Strainer is the parent class for the filters system.
  # New filters are mixed into the strainer class which is then instantiated for each liquid template render run.
  #
  # The Strainer only allows method calls defined in filters given to it via Strainer.global_filter,
  # Context#add_filters or Template.register_filter
  class Strainer #:nodoc:
    @@filters = []
    @@known_filters = Set.new
    @@known_methods = Set.new
    @@strainer_class_cache = Hash.new do |hash, filters|
      hash[filters] = Class.new(Strainer) do
        filters.each { |f| include f }
      end
    end

    def initialize(context)
      @context = context
    end

    def self.global_filter(filter)
      raise ArgumentError, "Passed filter is not a module" unless filter.is_a?(Module)
      add_known_filter(filter)
      @@filters << filter unless @@filters.include?(filter)
    end

    def self.add_known_filter(filter)
      unless @@known_filters.include?(filter)
        @@method_blacklist ||= Set.new(Strainer.instance_methods.map(&:to_s))
        new_methods = filter.instance_methods.map(&:to_s)
        new_methods.reject!{ |m| @@method_blacklist.include?(m) }
        @@known_methods.merge(new_methods)
        @@known_filters.add(filter)
      end
    end

    def self.strainer_class_cache
      @@strainer_class_cache
    end

    def self.create(context, filters = [])
      filters = @@filters + filters
      strainer_class_cache[filters].new(context)
    end

    def invoke(method, *args)
      if invokable?(method)
        send(method, *args)
      else
        args.first
      end
    rescue ::ArgumentError => e
      raise Liquid::ArgumentError.new(e.message)
    end

    def invokable?(method)
      @@known_methods.include?(method.to_s) && respond_to?(method)
    end
  end
end

Version data entries

7 entries across 7 versions & 2 rubygems

Version Path
locomotivecms-liquid-4.0.0 lib/liquid/strainer.rb
locomotivecms-liquid-4.0.0.alpha2 lib/liquid/strainer.rb
locomotivecms-liquid-4.0.0.alpha1 lib/liquid/strainer.rb
locomotivecms-liquid-4.0.0.alpha lib/liquid/strainer.rb
liquid-3.0.1 lib/liquid/strainer.rb
liquid-3.0.0 lib/liquid/strainer.rb
liquid-3.0.0.rc1 lib/liquid/strainer.rb