File: drop.rb

package info (click to toggle)
ruby-liquid 2.6.1-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 460 kB
  • ctags: 745
  • sloc: ruby: 4,166; makefile: 4
file content (61 lines) | stat: -rw-r--r-- 1,752 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
require 'set'

module Liquid

  # A drop in liquid is a class which allows you to export DOM like things to liquid.
  # Methods of drops are callable.
  # The main use for liquid drops is to implement lazy loaded objects.
  # If you would like to make data available to the web designers which you don't want loaded unless needed then
  # a drop is a great way to do that.
  #
  # Example:
  #
  #   class ProductDrop < Liquid::Drop
  #     def top_sales
  #       Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
  #     end
  #   end
  #
  #   tmpl = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {%endfor%} '  )
  #   tmpl.render('product' => ProductDrop.new ) # will invoke top_sales query.
  #
  # Your drop can either implement the methods sans any parameters or implement the before_method(name) method which is a
  # catch all.
  class Drop
    attr_writer :context

    EMPTY_STRING = ''.freeze

    # Catch all for the method
    def before_method(method)
      nil
    end

    # called by liquid to invoke a drop
    def invoke_drop(method_or_key)
      if method_or_key && method_or_key != EMPTY_STRING && self.class.invokable?(method_or_key)
        send(method_or_key)
      else
        before_method(method_or_key)
      end
    end

    def has_key?(name)
      true
    end

    def to_liquid
      self
    end

    alias :[] :invoke_drop

    private

    # Check for method existence without invoking respond_to?, which creates symbols
    def self.invokable?(method_name)
      @invokable_methods ||= Set.new(["to_liquid"] + (public_instance_methods - Liquid::Drop.public_instance_methods).map(&:to_s))
      @invokable_methods.include?(method_name.to_s)
    end
  end
end