liquid 2.0.0 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG +10 -6
- data/Rakefile +27 -12
- data/lib/extras/liquid_view.rb +27 -16
- data/lib/liquid.rb +3 -3
- data/lib/liquid/block.rb +30 -26
- data/lib/liquid/condition.rb +31 -34
- data/lib/liquid/context.rb +47 -25
- data/lib/liquid/document.rb +7 -7
- data/lib/liquid/drop.rb +17 -16
- data/lib/liquid/htmltags.rb +27 -27
- data/lib/liquid/module_ex.rb +4 -4
- data/lib/liquid/standardfilters.rb +18 -5
- data/lib/liquid/strainer.rb +17 -18
- data/lib/liquid/tag.rb +8 -8
- data/lib/liquid/tags/assign.rb +1 -1
- data/lib/liquid/tags/capture.rb +9 -9
- data/lib/liquid/tags/case.rb +2 -2
- data/lib/liquid/tags/cycle.rb +3 -3
- data/lib/liquid/tags/for.rb +1 -1
- data/lib/liquid/tags/if.rb +3 -2
- data/lib/liquid/tags/include.rb +2 -1
- data/lib/liquid/template.rb +57 -54
- data/lib/liquid/variable.rb +7 -8
- metadata +25 -21
- data/init.rb +0 -8
- data/test/test_helper.rb +0 -20
data/CHANGELOG
CHANGED
@@ -1,9 +1,13 @@
|
|
1
|
+
* Ruby 1.9.1 bugfixes
|
2
|
+
|
3
|
+
* Fix LiquidView for Rails 2.2. Fix local assigns for all versions of Rails
|
4
|
+
|
1
5
|
* Fixed gem install rake task
|
2
6
|
* Improve Error encapsulation in liquid by maintaining a own set of exceptions instead of relying on ruby build ins
|
3
7
|
|
4
8
|
* Added If with or / and expressions
|
5
9
|
|
6
|
-
* Implemented .to_liquid for all objects which can be passed to liquid like Strings Arrays Hashes Numerics and Booleans. To export new objects to liquid just implement .to_liquid on them and return objects which themselves have .to_liquid methods.
|
10
|
+
* Implemented .to_liquid for all objects which can be passed to liquid like Strings Arrays Hashes Numerics and Booleans. To export new objects to liquid just implement .to_liquid on them and return objects which themselves have .to_liquid methods.
|
7
11
|
|
8
12
|
* Added more tags to standard library
|
9
13
|
|
@@ -22,17 +26,17 @@
|
|
22
26
|
* Fixed bug with string filter parameters failing to tolerate commas in strings. [Paul Hammond]
|
23
27
|
|
24
28
|
* Improved filter parameters. Filter parameters are now context sensitive; Types are resolved according to the rules of the context. Multiple parameters are now separated by the Liquid::ArgumentSeparator: , by default [Paul Hammond]
|
25
|
-
|
26
|
-
{{ 'Typo' | link_to: 'http://typo.leetsoft.com', 'Typo - a modern weblog engine' }}
|
27
|
-
|
28
29
|
|
29
|
-
|
30
|
+
{{ 'Typo' | link_to: 'http://typo.leetsoft.com', 'Typo - a modern weblog engine' }}
|
31
|
+
|
32
|
+
|
33
|
+
* Added Liquid::Drop. A base class which you can use for exporting proxy objects to liquid which can acquire more data when used in liquid. [Tobias Luetke]
|
30
34
|
|
31
35
|
class ProductDrop < Liquid::Drop
|
32
36
|
def top_sales
|
33
37
|
Shop.current.products.find(:all, :order => 'sales', :limit => 10 )
|
34
38
|
end
|
35
|
-
end
|
39
|
+
end
|
36
40
|
t = Liquid::Template.parse( ' {% for product in product.top_sales %} {{ product.name }} {% endfor %} ' )
|
37
41
|
t.render('product' => ProductDrop.new )
|
38
42
|
|
data/Rakefile
CHANGED
@@ -1,11 +1,10 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
require 'rubygems'
|
3
3
|
require 'rake'
|
4
|
-
require '
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/gempackagetask'
|
5
6
|
|
6
|
-
|
7
|
-
PKG_NAME = "liquid"
|
8
|
-
PKG_DESC = "A secure non evaling end user template engine with aesthetic markup."
|
7
|
+
task :default => 'test'
|
9
8
|
|
10
9
|
Rake::TestTask.new(:test) do |t|
|
11
10
|
t.libs << "lib"
|
@@ -14,11 +13,27 @@ Rake::TestTask.new(:test) do |t|
|
|
14
13
|
t.verbose = false
|
15
14
|
end
|
16
15
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
16
|
+
gemspec = eval(File.read('liquid.gemspec'))
|
17
|
+
Rake::GemPackageTask.new(gemspec) do |pkg|
|
18
|
+
pkg.gem_spec = gemspec
|
19
|
+
end
|
20
|
+
|
21
|
+
namespace :profile do
|
22
|
+
|
23
|
+
|
24
|
+
task :default => [:run]
|
25
|
+
|
26
|
+
desc "Run the liquid profile/perforamce coverage"
|
27
|
+
task :run do
|
28
|
+
|
29
|
+
ruby "performance/shopify.rb"
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Run KCacheGrind"
|
34
|
+
task :grind => :run do
|
35
|
+
system "kcachegrind /tmp/liquid.rubyprof_calltreeprinter.txt"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
|
data/lib/extras/liquid_view.rb
CHANGED
@@ -5,32 +5,43 @@
|
|
5
5
|
#
|
6
6
|
# ActionView::Base::register_template_handler :liquid, LiquidView
|
7
7
|
class LiquidView
|
8
|
+
PROTECTED_ASSIGNS = %w( template_root response _session template_class action_name request_origin session template
|
9
|
+
_response url _request _cookies variables_added _flash params _headers request cookies
|
10
|
+
ignore_missing_templates flash _params logger before_filter_chain_aborted headers )
|
11
|
+
PROTECTED_INSTANCE_VARIABLES = %w( @_request @controller @_first_render @_memoized__pick_template @view_paths
|
12
|
+
@helpers @assigns_added @template @_render_stack @template_format @assigns )
|
13
|
+
|
14
|
+
def self.call(template)
|
15
|
+
"LiquidView.new(self).render(template, local_assigns)"
|
16
|
+
end
|
8
17
|
|
9
|
-
def initialize(
|
10
|
-
@
|
18
|
+
def initialize(view)
|
19
|
+
@view = view
|
11
20
|
end
|
12
21
|
|
13
|
-
|
14
|
-
|
15
|
-
@action_view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'
|
16
|
-
assigns = @action_view.assigns.dup
|
22
|
+
def render(template, local_assigns = nil)
|
23
|
+
@view.controller.headers["Content-Type"] ||= 'text/html; charset=utf-8'
|
17
24
|
|
18
|
-
#
|
19
|
-
if template.respond_to? :
|
20
|
-
|
21
|
-
|
25
|
+
# Rails 2.2 Template has source, but not locals
|
26
|
+
if template.respond_to?(:source) && !template.respond_to?(:locals)
|
27
|
+
assigns = (@view.instance_variables - PROTECTED_INSTANCE_VARIABLES).inject({}) do |hash, ivar|
|
28
|
+
hash[ivar[1..-1]] = @view.instance_variable_get(ivar)
|
29
|
+
hash
|
30
|
+
end
|
22
31
|
else
|
23
|
-
|
24
|
-
local_assigns = local_assigns_for_rails_less_than_2_1_0
|
32
|
+
assigns = @view.assigns.reject{ |k,v| PROTECTED_ASSIGNS.include?(k) }
|
25
33
|
end
|
26
|
-
|
27
|
-
|
34
|
+
|
35
|
+
source = template.respond_to?(:source) ? template.source : template
|
36
|
+
local_assigns = (template.respond_to?(:locals) ? template.locals : local_assigns) || {}
|
37
|
+
|
38
|
+
if content_for_layout = @view.instance_variable_get("@content_for_layout")
|
28
39
|
assigns['content_for_layout'] = content_for_layout
|
29
40
|
end
|
30
|
-
assigns.merge!(local_assigns)
|
41
|
+
assigns.merge!(local_assigns.stringify_keys)
|
31
42
|
|
32
43
|
liquid = Liquid::Template.parse(source)
|
33
|
-
liquid.render(assigns, :filters => [@
|
44
|
+
liquid.render(assigns, :filters => [@view.controller.master_helper_module], :registers => {:action_view => @view, :controller => @view.controller})
|
34
45
|
end
|
35
46
|
|
36
47
|
def compilable?
|
data/lib/liquid.rb
CHANGED
@@ -29,11 +29,11 @@ module Liquid
|
|
29
29
|
TagStart = /\{\%/
|
30
30
|
TagEnd = /\%\}/
|
31
31
|
VariableSignature = /\(?[\w\-\.\[\]]\)?/
|
32
|
-
VariableSegment = /[\w\-]
|
32
|
+
VariableSegment = /[\w\-]/
|
33
33
|
VariableStart = /\{\{/
|
34
34
|
VariableEnd = /\}\}/
|
35
35
|
VariableIncompleteEnd = /\}\}?/
|
36
|
-
QuotedString = /"[^"]
|
36
|
+
QuotedString = /"[^"]*"|'[^']*'/
|
37
37
|
QuotedFragment = /#{QuotedString}|(?:[^\s,\|'"]|#{QuotedString})+/
|
38
38
|
StrictQuotedFragment = /"[^"]+"|'[^']+'|[^\s,\|,\:,\,]+/
|
39
39
|
FirstFilterArgument = /#{FilterArgumentSeparator}(?:#{StrictQuotedFragment})/
|
@@ -44,7 +44,7 @@ module Liquid
|
|
44
44
|
AnyStartingTag = /\{\{|\{\%/
|
45
45
|
PartialTemplateParser = /#{TagStart}.*?#{TagEnd}|#{VariableStart}.*?#{VariableIncompleteEnd}/
|
46
46
|
TemplateParser = /(#{PartialTemplateParser}|#{AnyStartingTag})/
|
47
|
-
VariableParser = /\[[^\]]+\]|#{VariableSegment}
|
47
|
+
VariableParser = /\[[^\]]+\]|#{VariableSegment}+\??/
|
48
48
|
end
|
49
49
|
|
50
50
|
require 'liquid/drop'
|
data/lib/liquid/block.rb
CHANGED
@@ -1,19 +1,23 @@
|
|
1
1
|
module Liquid
|
2
|
-
|
2
|
+
|
3
3
|
class Block < Tag
|
4
|
+
IsTag = /^#{TagStart}/
|
5
|
+
IsVariable = /^#{VariableStart}/
|
6
|
+
FullToken = /^#{TagStart}\s*(\w+)\s*(.*)?#{TagEnd}$/
|
7
|
+
ContentOfVariable = /^#{VariableStart}(.*)#{VariableEnd}$/
|
4
8
|
|
5
9
|
def parse(tokens)
|
6
10
|
@nodelist ||= []
|
7
11
|
@nodelist.clear
|
8
12
|
|
9
|
-
while token = tokens.shift
|
13
|
+
while token = tokens.shift
|
10
14
|
|
11
15
|
case token
|
12
|
-
when
|
13
|
-
if token =~
|
16
|
+
when IsTag
|
17
|
+
if token =~ FullToken
|
14
18
|
|
15
19
|
# if we found the proper block delimitor just end parsing here and let the outer block
|
16
|
-
# proceed
|
20
|
+
# proceed
|
17
21
|
if block_delimiter == $1
|
18
22
|
end_tag
|
19
23
|
return
|
@@ -23,33 +27,33 @@ module Liquid
|
|
23
27
|
if tag = Template.tags[$1]
|
24
28
|
@nodelist << tag.new($1, $2, tokens)
|
25
29
|
else
|
26
|
-
# this tag is not registered with the system
|
30
|
+
# this tag is not registered with the system
|
27
31
|
# pass it to the current block for special handling or error reporting
|
28
32
|
unknown_tag($1, $2, tokens)
|
29
|
-
end
|
33
|
+
end
|
30
34
|
else
|
31
35
|
raise SyntaxError, "Tag '#{token}' was not properly terminated with regexp: #{TagEnd.inspect} "
|
32
36
|
end
|
33
|
-
when
|
37
|
+
when IsVariable
|
34
38
|
@nodelist << create_variable(token)
|
35
39
|
when ''
|
36
40
|
# pass
|
37
41
|
else
|
38
42
|
@nodelist << token
|
39
43
|
end
|
40
|
-
end
|
41
|
-
|
42
|
-
# Make sure that its ok to end parsing in the current block.
|
43
|
-
# Effectively this method will throw and exception unless the current block is
|
44
|
-
# of type Document
|
44
|
+
end
|
45
|
+
|
46
|
+
# Make sure that its ok to end parsing in the current block.
|
47
|
+
# Effectively this method will throw and exception unless the current block is
|
48
|
+
# of type Document
|
45
49
|
assert_missing_delimitation!
|
46
|
-
end
|
47
|
-
|
48
|
-
def end_tag
|
50
|
+
end
|
51
|
+
|
52
|
+
def end_tag
|
49
53
|
end
|
50
54
|
|
51
55
|
def unknown_tag(tag, params, tokens)
|
52
|
-
case tag
|
56
|
+
case tag
|
53
57
|
when 'else'
|
54
58
|
raise SyntaxError, "#{block_name} tag does not expect else tag"
|
55
59
|
when 'end'
|
@@ -61,14 +65,14 @@ module Liquid
|
|
61
65
|
|
62
66
|
def block_delimiter
|
63
67
|
"end#{block_name}"
|
64
|
-
end
|
68
|
+
end
|
65
69
|
|
66
70
|
def block_name
|
67
71
|
@tag_name
|
68
72
|
end
|
69
73
|
|
70
74
|
def create_variable(token)
|
71
|
-
token.scan(
|
75
|
+
token.scan(ContentOfVariable) do |content|
|
72
76
|
return Variable.new(content.first)
|
73
77
|
end
|
74
78
|
raise SyntaxError.new("Variable '#{token}' was not properly terminated with regexp: #{VariableEnd.inspect} ")
|
@@ -77,7 +81,7 @@ module Liquid
|
|
77
81
|
def render(context)
|
78
82
|
render_all(@nodelist, context)
|
79
83
|
end
|
80
|
-
|
84
|
+
|
81
85
|
protected
|
82
86
|
|
83
87
|
def assert_missing_delimitation!
|
@@ -86,12 +90,12 @@ module Liquid
|
|
86
90
|
|
87
91
|
def render_all(list, context)
|
88
92
|
list.collect do |token|
|
89
|
-
begin
|
93
|
+
begin
|
90
94
|
token.respond_to?(:render) ? token.render(context) : token
|
91
|
-
rescue Exception => e
|
95
|
+
rescue Exception => e
|
92
96
|
context.handle_error(e)
|
93
|
-
end
|
94
|
-
end
|
97
|
+
end
|
98
|
+
end
|
95
99
|
end
|
96
|
-
end
|
97
|
-
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/liquid/condition.rb
CHANGED
@@ -3,7 +3,7 @@ module Liquid
|
|
3
3
|
#
|
4
4
|
# Example:
|
5
5
|
#
|
6
|
-
# c = Condition.new('1', '==', '1')
|
6
|
+
# c = Condition.new('1', '==', '1')
|
7
7
|
# c.evaluate #=> true
|
8
8
|
#
|
9
9
|
class Condition #:nodoc:
|
@@ -15,35 +15,35 @@ module Liquid
|
|
15
15
|
'>' => :>,
|
16
16
|
'>=' => :>=,
|
17
17
|
'<=' => :<=,
|
18
|
-
'contains' => lambda { |cond, left, right| left.include?(right) }
|
18
|
+
'contains' => lambda { |cond, left, right| left && right ? left.include?(right) : false }
|
19
19
|
}
|
20
|
-
|
20
|
+
|
21
21
|
def self.operators
|
22
22
|
@@operators
|
23
23
|
end
|
24
24
|
|
25
25
|
attr_reader :attachment
|
26
26
|
attr_accessor :left, :operator, :right
|
27
|
-
|
27
|
+
|
28
28
|
def initialize(left = nil, operator = nil, right = nil)
|
29
29
|
@left, @operator, @right = left, operator, right
|
30
30
|
@child_relation = nil
|
31
31
|
@child_condition = nil
|
32
32
|
end
|
33
|
-
|
33
|
+
|
34
34
|
def evaluate(context = Context.new)
|
35
|
-
result = interpret_condition(left, right, operator, context)
|
36
|
-
|
35
|
+
result = interpret_condition(left, right, operator, context)
|
36
|
+
|
37
37
|
case @child_relation
|
38
|
-
when :or
|
38
|
+
when :or
|
39
39
|
result || @child_condition.evaluate(context)
|
40
|
-
when :and
|
40
|
+
when :and
|
41
41
|
result && @child_condition.evaluate(context)
|
42
42
|
else
|
43
43
|
result
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
47
|
def or(condition)
|
48
48
|
@child_relation, @child_condition = :or, condition
|
49
49
|
end
|
@@ -51,25 +51,25 @@ module Liquid
|
|
51
51
|
def and(condition)
|
52
52
|
@child_relation, @child_condition = :and, condition
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
def attach(attachment)
|
56
56
|
@attachment = attachment
|
57
57
|
end
|
58
|
-
|
58
|
+
|
59
59
|
def else?
|
60
60
|
false
|
61
|
-
end
|
62
|
-
|
61
|
+
end
|
62
|
+
|
63
63
|
def inspect
|
64
64
|
"#<Condition #{[@left, @operator, @right].compact.join(' ')}>"
|
65
65
|
end
|
66
|
-
|
66
|
+
|
67
67
|
private
|
68
|
-
|
68
|
+
|
69
69
|
def equal_variables(left, right)
|
70
70
|
if left.is_a?(Symbol)
|
71
71
|
if right.respond_to?(left)
|
72
|
-
return right.send(left.to_s)
|
72
|
+
return right.send(left.to_s)
|
73
73
|
else
|
74
74
|
return nil
|
75
75
|
end
|
@@ -77,47 +77,44 @@ module Liquid
|
|
77
77
|
|
78
78
|
if right.is_a?(Symbol)
|
79
79
|
if left.respond_to?(right)
|
80
|
-
return left.send(right.to_s)
|
80
|
+
return left.send(right.to_s)
|
81
81
|
else
|
82
82
|
return nil
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
left == right
|
87
|
-
end
|
86
|
+
left == right
|
87
|
+
end
|
88
88
|
|
89
89
|
def interpret_condition(left, right, op, context)
|
90
|
-
|
91
|
-
#
|
92
|
-
# a single variable. We can just poll this variable from the context and
|
90
|
+
# If the operator is empty this means that the decision statement is just
|
91
|
+
# a single variable. We can just poll this variable from the context and
|
93
92
|
# return this as the result.
|
94
|
-
return context[left] if op == nil
|
93
|
+
return context[left] if op == nil
|
95
94
|
|
96
95
|
left, right = context[left], context[right]
|
97
|
-
|
98
96
|
|
99
97
|
operation = self.class.operators[op] || raise(ArgumentError.new("Unknown operator #{op}"))
|
100
98
|
|
101
99
|
if operation.respond_to?(:call)
|
102
100
|
operation.call(self, left, right)
|
103
|
-
elsif left.respond_to?(operation) and right.respond_to?(operation)
|
101
|
+
elsif left.respond_to?(operation) and right.respond_to?(operation)
|
104
102
|
left.send(operation, right)
|
105
103
|
else
|
106
104
|
nil
|
107
105
|
end
|
108
|
-
end
|
109
|
-
end
|
106
|
+
end
|
107
|
+
end
|
110
108
|
|
111
109
|
|
112
110
|
class ElseCondition < Condition
|
113
|
-
|
114
|
-
def else?
|
111
|
+
def else?
|
115
112
|
true
|
116
113
|
end
|
117
|
-
|
114
|
+
|
118
115
|
def evaluate(context)
|
119
116
|
true
|
120
117
|
end
|
121
118
|
end
|
122
119
|
|
123
|
-
end
|
120
|
+
end
|
data/lib/liquid/context.rb
CHANGED
@@ -13,14 +13,15 @@ module Liquid
|
|
13
13
|
#
|
14
14
|
# context['bob'] #=> nil class Context
|
15
15
|
class Context
|
16
|
-
attr_reader :scopes
|
17
|
-
attr_reader :errors, :registers
|
16
|
+
attr_reader :scopes, :errors, :registers, :environments
|
18
17
|
|
19
|
-
def initialize(
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
18
|
+
def initialize(environments = {}, outer_scope = {}, registers = {}, rethrow_errors = false)
|
19
|
+
@environments = [environments].flatten
|
20
|
+
@scopes = [(outer_scope || {})]
|
21
|
+
@registers = registers
|
22
|
+
@errors = []
|
23
23
|
@rethrow_errors = rethrow_errors
|
24
|
+
squash_instance_assigns_with_environments
|
24
25
|
end
|
25
26
|
|
26
27
|
def strainer
|
@@ -61,9 +62,9 @@ module Liquid
|
|
61
62
|
end
|
62
63
|
|
63
64
|
# push new local scope on the stack. use <tt>Context#stack</tt> instead
|
64
|
-
def push
|
65
|
+
def push(new_scope={})
|
65
66
|
raise StackLevelError, "Nesting too deep" if @scopes.length > 100
|
66
|
-
@scopes.unshift(
|
67
|
+
@scopes.unshift(new_scope)
|
67
68
|
end
|
68
69
|
|
69
70
|
# merge a hash of variables in the current local scope
|
@@ -86,9 +87,9 @@ module Liquid
|
|
86
87
|
# end
|
87
88
|
# context['var] #=> nil
|
88
89
|
#
|
89
|
-
def stack(
|
90
|
+
def stack(new_scope={},&block)
|
90
91
|
result = nil
|
91
|
-
push
|
92
|
+
push(new_scope)
|
92
93
|
begin
|
93
94
|
result = yield
|
94
95
|
ensure
|
@@ -96,6 +97,10 @@ module Liquid
|
|
96
97
|
end
|
97
98
|
result
|
98
99
|
end
|
100
|
+
|
101
|
+
def clear_instance_assigns
|
102
|
+
@scopes[0] = {}
|
103
|
+
end
|
99
104
|
|
100
105
|
# Only allow String, Numeric, Hash, Array, Proc, Boolean or <tt>Liquid::Drop</tt>
|
101
106
|
def []=(key, value)
|
@@ -133,9 +138,6 @@ module Liquid
|
|
133
138
|
:blank?
|
134
139
|
when 'empty'
|
135
140
|
:empty?
|
136
|
-
# filtered variables
|
137
|
-
when SpacelessFilter
|
138
|
-
filtered_variable(key)
|
139
141
|
# Single quoted strings
|
140
142
|
when /^'(.*)'$/
|
141
143
|
$1.to_s
|
@@ -159,16 +161,21 @@ module Liquid
|
|
159
161
|
# fetches an object starting at the local scope and then moving up
|
160
162
|
# the hierachy
|
161
163
|
def find_variable(key)
|
162
|
-
@scopes.
|
163
|
-
|
164
|
-
|
165
|
-
variable =
|
166
|
-
|
167
|
-
|
168
|
-
|
164
|
+
scope = @scopes.find { |s| s.has_key?(key) }
|
165
|
+
if scope.nil?
|
166
|
+
@environments.each do |e|
|
167
|
+
if variable = lookup_and_evaluate(e, key)
|
168
|
+
scope = e
|
169
|
+
break
|
170
|
+
end
|
169
171
|
end
|
170
172
|
end
|
171
|
-
|
173
|
+
scope ||= @environments.last || @scopes.last
|
174
|
+
variable ||= lookup_and_evaluate(scope, key)
|
175
|
+
|
176
|
+
variable = variable.to_liquid
|
177
|
+
variable.context = self if variable.respond_to?(:context=)
|
178
|
+
return variable
|
172
179
|
end
|
173
180
|
|
174
181
|
# resolves namespaced queries gracefully.
|
@@ -200,8 +207,7 @@ module Liquid
|
|
200
207
|
(object.respond_to?(:fetch) and part.is_a?(Integer)))
|
201
208
|
|
202
209
|
# if its a proc we will replace the entry with the proc
|
203
|
-
res = object
|
204
|
-
res = object[part] = res.call(self) if res.is_a?(Proc) and object.respond_to?(:[]=)
|
210
|
+
res = lookup_and_evaluate(object, part)
|
205
211
|
object = res.to_liquid
|
206
212
|
|
207
213
|
# Some special cases. If the part wasn't in square brackets and
|
@@ -225,8 +231,24 @@ module Liquid
|
|
225
231
|
object
|
226
232
|
end
|
227
233
|
|
228
|
-
def
|
229
|
-
|
234
|
+
def lookup_and_evaluate(obj, key)
|
235
|
+
if (value = obj[key]).is_a?(Proc) && obj.respond_to?(:[]=)
|
236
|
+
obj[key] = value.call(self)
|
237
|
+
else
|
238
|
+
value
|
239
|
+
end
|
230
240
|
end
|
241
|
+
|
242
|
+
def squash_instance_assigns_with_environments
|
243
|
+
@scopes.last.each_key do |k|
|
244
|
+
@environments.each do |env|
|
245
|
+
if env.has_key?(k)
|
246
|
+
scopes.last[k] = lookup_and_evaluate(env, k)
|
247
|
+
break
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
|
231
253
|
end
|
232
254
|
end
|