flex 0.4.2 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +1 -1
- data/README.md +46 -7
- data/VERSION +1 -1
- data/flex.gemspec +13 -19
- data/lib/flex.rb +66 -392
- data/lib/flex/api_stubs.rb +1268 -0
- data/lib/flex/api_templates/cluster_api.yml +94 -0
- data/lib/flex/api_templates/core_api.yml +202 -0
- data/lib/flex/api_templates/indices_api.yml +304 -0
- data/lib/flex/class_proxy/base.rb +20 -6
- data/lib/flex/class_proxy/templates.rb +97 -0
- data/lib/flex/class_proxy/templates/doc.rb +91 -0
- data/lib/flex/class_proxy/templates/search.rb +72 -0
- data/lib/flex/configuration.rb +17 -49
- data/lib/flex/deprecation.rb +153 -0
- data/lib/flex/errors.rb +2 -1
- data/lib/flex/http_clients/base.rb +15 -0
- data/lib/flex/http_clients/loader.rb +51 -0
- data/lib/flex/http_clients/patron.rb +9 -7
- data/lib/flex/http_clients/rest_client.rb +6 -8
- data/lib/flex/logger.rb +24 -3
- data/lib/flex/prog_bar.rb +11 -6
- data/lib/flex/rails.rb +1 -13
- data/lib/flex/result.rb +8 -2
- data/lib/flex/result/document.rb +42 -13
- data/lib/flex/result/multi_get.rb +24 -0
- data/lib/flex/result/search.rb +1 -24
- data/lib/flex/struct/array.rb +25 -0
- data/lib/flex/struct/hash.rb +105 -0
- data/lib/flex/{result/collection.rb → struct/paginable.rb} +16 -9
- data/lib/flex/struct/prunable.rb +60 -0
- data/lib/flex/struct/symbolize.rb +27 -0
- data/lib/flex/tasks.rb +26 -86
- data/lib/flex/template.rb +60 -120
- data/lib/flex/template/common.rb +42 -0
- data/lib/flex/template/logger.rb +66 -0
- data/lib/flex/template/partial.rb +12 -15
- data/lib/flex/template/search.rb +6 -6
- data/lib/flex/template/slim_search.rb +1 -1
- data/lib/flex/template/tags.rb +19 -9
- data/lib/flex/templates.rb +20 -0
- data/lib/flex/utility_methods.rb +80 -89
- data/lib/flex/utils.rb +68 -25
- data/lib/flex/variables.rb +55 -4
- data/lib/tasks.rake +28 -0
- metadata +61 -85
- data/bin/flexes +0 -174
- data/lib/flex/api_methods.yml +0 -108
- data/lib/flex/class_proxy/loader.rb +0 -102
- data/lib/flex/class_proxy/model.rb +0 -45
- data/lib/flex/class_proxy/model_sync.rb +0 -23
- data/lib/flex/class_proxy/related_model.rb +0 -23
- data/lib/flex/instance_proxy/base.rb +0 -29
- data/lib/flex/instance_proxy/model.rb +0 -102
- data/lib/flex/instance_proxy/related_model.rb +0 -7
- data/lib/flex/loader.rb +0 -18
- data/lib/flex/manager.rb +0 -61
- data/lib/flex/model.rb +0 -24
- data/lib/flex/rails/engine.rb +0 -23
- data/lib/flex/rails/helper.rb +0 -16
- data/lib/flex/related_model.rb +0 -16
- data/lib/flex/result/indifferent_access.rb +0 -11
- data/lib/flex/result/source_document.rb +0 -63
- data/lib/flex/result/source_search.rb +0 -32
- data/lib/flex/structure/indifferent_access.rb +0 -44
- data/lib/flex/structure/mergeable.rb +0 -21
- data/lib/flex/template/base.rb +0 -41
- data/lib/flex/template/info.rb +0 -68
- data/lib/generators/flex/setup/setup_generator.rb +0 -48
- data/lib/generators/flex/setup/templates/flex_config.yml +0 -16
- data/lib/generators/flex/setup/templates/flex_dir/es.rb.erb +0 -18
- data/lib/generators/flex/setup/templates/flex_dir/es.yml.erb +0 -19
- data/lib/generators/flex/setup/templates/flex_dir/es_extender.rb.erb +0 -17
- data/lib/generators/flex/setup/templates/flex_initializer.rb.erb +0 -44
- data/lib/tasks/index.rake +0 -17
- data/test/flex.irt +0 -143
- data/test/flex/configuration.irt +0 -53
- data/test/irt_helper.rb +0 -12
@@ -1,16 +1,18 @@
|
|
1
1
|
module Flex
|
2
|
-
|
3
|
-
module
|
2
|
+
module Struct
|
3
|
+
module Paginable
|
4
4
|
|
5
|
-
|
5
|
+
attr_accessor :total_entries, :variables
|
6
6
|
|
7
7
|
def setup(total_entries, variables)
|
8
8
|
@total_entries = total_entries
|
9
9
|
@variables = variables
|
10
|
+
self
|
10
11
|
end
|
11
12
|
|
12
13
|
def per_page
|
13
|
-
(@variables[:per_page] || @variables[:
|
14
|
+
(@variables[:per_page] || @variables[:limit_value] ||
|
15
|
+
@variables[:params] && @variables[:params][:size] || 10).to_i
|
14
16
|
end
|
15
17
|
|
16
18
|
def total_pages
|
@@ -18,11 +20,7 @@ module Flex
|
|
18
20
|
end
|
19
21
|
|
20
22
|
def current_page
|
21
|
-
|
22
|
-
@variables[:page].to_i
|
23
|
-
else
|
24
|
-
(per_page + (@variables[:from]||0).to_i) / per_page
|
25
|
-
end
|
23
|
+
(@variables[:page] || @variables[:current_page] || 1).to_i
|
26
24
|
end
|
27
25
|
|
28
26
|
def previous_page
|
@@ -33,6 +31,14 @@ module Flex
|
|
33
31
|
current_page < total_pages ? (current_page + 1) : nil
|
34
32
|
end
|
35
33
|
|
34
|
+
def last_page?
|
35
|
+
total_pages == current_page
|
36
|
+
end
|
37
|
+
|
38
|
+
def first_page?
|
39
|
+
current_page == 1
|
40
|
+
end
|
41
|
+
|
36
42
|
def offset
|
37
43
|
per_page * (current_page - 1)
|
38
44
|
end
|
@@ -48,4 +54,5 @@ module Flex
|
|
48
54
|
|
49
55
|
end
|
50
56
|
end
|
57
|
+
|
51
58
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Flex
|
2
|
+
module Struct
|
3
|
+
module Prunable
|
4
|
+
|
5
|
+
extend self
|
6
|
+
|
7
|
+
VALUES = [ nil, '', {}, [], false ]
|
8
|
+
|
9
|
+
class Value
|
10
|
+
class << self
|
11
|
+
def to_s; '' end
|
12
|
+
alias_method :===, :==
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def prune_blanks(obj)
|
17
|
+
prune(obj, *VALUES) || {}
|
18
|
+
end
|
19
|
+
|
20
|
+
# prunes the branch when the leaf is Prunable
|
21
|
+
# and compact.flatten the Array values
|
22
|
+
# values are the prunable values, like VALUES or Prunable::Value,
|
23
|
+
# or any arbitrary value
|
24
|
+
def prune(obj, *values)
|
25
|
+
case
|
26
|
+
when values.include?(obj)
|
27
|
+
obj
|
28
|
+
when obj.is_a?(::Array)
|
29
|
+
return obj if obj.empty?
|
30
|
+
ar = []
|
31
|
+
obj.each do |i|
|
32
|
+
pruned = prune(i, *values)
|
33
|
+
next if values.include?(pruned)
|
34
|
+
ar << pruned
|
35
|
+
end
|
36
|
+
a = ar.compact.flatten
|
37
|
+
a.empty? ? values.first : a
|
38
|
+
when obj.is_a?(::Hash)
|
39
|
+
return obj if obj.empty?
|
40
|
+
h = {}
|
41
|
+
obj.each do |k, v|
|
42
|
+
pruned = prune(v, *values)
|
43
|
+
next if values.include?(pruned)
|
44
|
+
# when a key is prunable merges the value if it is a hash (allows merging of partials)
|
45
|
+
if VALUES.include?(k)
|
46
|
+
h.merge!(pruned) if pruned.is_a?(::Hash)
|
47
|
+
else
|
48
|
+
h[k] = pruned
|
49
|
+
end
|
50
|
+
end
|
51
|
+
h.empty? ? values.first : h
|
52
|
+
else
|
53
|
+
obj
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
Prunable = Struct::Prunable
|
60
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module Flex
|
2
|
+
module Struct
|
3
|
+
module AsIs end
|
4
|
+
module Symbolize
|
5
|
+
|
6
|
+
def symbolize(obj)
|
7
|
+
case obj
|
8
|
+
when Flex::Struct::Hash, Flex::Struct::Array, Flex::Struct::AsIs
|
9
|
+
obj
|
10
|
+
when ::Hash
|
11
|
+
h = Struct::Hash.new
|
12
|
+
obj.each do |k,v|
|
13
|
+
h[k.to_sym] = symbolize(v)
|
14
|
+
end
|
15
|
+
h
|
16
|
+
when ::Array
|
17
|
+
a = Struct::Array.new
|
18
|
+
obj.each{|i| a << i}
|
19
|
+
a
|
20
|
+
else
|
21
|
+
obj
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/flex/tasks.rb
CHANGED
@@ -1,10 +1,23 @@
|
|
1
1
|
module Flex
|
2
|
-
|
3
|
-
|
2
|
+
class Tasks
|
3
|
+
|
4
|
+
attr_reader :options
|
5
|
+
|
6
|
+
def initialize(overrides={})
|
7
|
+
options = Flex::Utils.env2options *default_options.keys
|
8
|
+
options[:index] = options[:index].split(',') if options[:index]
|
9
|
+
@options = default_options.merge(options).merge(overrides)
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_options
|
13
|
+
@default_options ||= { :force => false,
|
14
|
+
:index => Conf.variables[:index],
|
15
|
+
:config_file => Conf.config_file }
|
16
|
+
end
|
4
17
|
|
5
18
|
def create_indices
|
6
19
|
indices.each do |index|
|
7
|
-
delete_index(index) if
|
20
|
+
delete_index(index) if options[:force]
|
8
21
|
raise ExistingIndexError, "#{index.inspect} already exists. Please use FORCE=1 if you want to delete it first." \
|
9
22
|
if exist?(index)
|
10
23
|
create(index)
|
@@ -15,96 +28,24 @@ module Flex
|
|
15
28
|
indices.each { |index| delete_index(index) }
|
16
29
|
end
|
17
30
|
|
18
|
-
def
|
19
|
-
|
20
|
-
|
21
|
-
Configuration.debug = !!ENV['FLEX_DEBUG']
|
22
|
-
batch_size = ENV['BATCH_SIZE'] && ENV['BATCH_SIZE'].to_i || 1000
|
23
|
-
options = {}
|
24
|
-
if ENV['IMPORT_OPTIONS']
|
25
|
-
ENV['IMPORT_OPTIONS'].split('&').each do |pair|
|
26
|
-
k, v = pair.split('=')
|
27
|
-
options[k.to_sym] = v
|
28
|
-
end
|
29
|
-
end
|
30
|
-
deleted = []
|
31
|
-
|
32
|
-
models.each do |klass|
|
33
|
-
index = klass.flex.index
|
34
|
-
|
35
|
-
if ENV['FORCE']
|
36
|
-
unless deleted.include?(index)
|
37
|
-
delete_index(index)
|
38
|
-
deleted << index
|
39
|
-
puts "#{index} index deleted"
|
40
|
-
end
|
41
|
-
end
|
42
|
-
|
43
|
-
unless exist?(index)
|
44
|
-
create(index)
|
45
|
-
puts "#{index} index created"
|
46
|
-
end
|
47
|
-
|
48
|
-
if defined?(Mongoid::Document) && klass.ancestors.include?(Mongoid::Document)
|
49
|
-
def klass.find_in_batches(options={})
|
50
|
-
0.step(count, options[:batch_size]) do |offset|
|
51
|
-
yield limit(options[:batch_size]).skip(offset).to_a
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
unless klass.respond_to?(:find_in_batches)
|
57
|
-
STDERR.puts "[ERROR] Class #{klass} does not respond to :find_in_batches. Skipped."
|
58
|
-
next
|
59
|
-
end
|
60
|
-
|
61
|
-
pbar = ProgBar.new(klass.count, batch_size, "Class #{klass}: ")
|
62
|
-
|
63
|
-
klass.find_in_batches(:batch_size => batch_size) do |array|
|
64
|
-
opts = {:index => index}.merge(options)
|
65
|
-
result = Flex.import_collection(array, opts) || next
|
66
|
-
pbar.process_result(result, array.size)
|
67
|
-
end
|
68
|
-
|
69
|
-
pbar.finish
|
70
|
-
end
|
31
|
+
def config_hash
|
32
|
+
@config_hash ||= ( hash = YAML.load(Utils.erb_process(config_path))
|
33
|
+
Utils.delete_allcaps_keys(hash) )
|
71
34
|
end
|
72
35
|
|
73
|
-
|
36
|
+
private
|
74
37
|
|
75
38
|
def indices
|
76
|
-
|
77
|
-
|
78
|
-
indices = [indices] unless indices.is_a?(Array)
|
79
|
-
indices
|
39
|
+
i = options[:index] || config_hash.keys
|
40
|
+
i.is_a?(Array) ? i : [i]
|
80
41
|
end
|
81
42
|
|
82
43
|
def exist?(index)
|
83
44
|
Flex.exist?(:index => index)
|
84
45
|
end
|
85
46
|
|
86
|
-
def
|
87
|
-
@
|
88
|
-
@indices_yaml = ENV['CONFIG_FILE'] || Flex::Configuration.config_file
|
89
|
-
raise Errno::ENOENT, "no such file or directory #{@indices_yaml.inspect}. " +
|
90
|
-
'Please, use CONFIG_FILE=/path/to/index.yml ' +
|
91
|
-
'or set the Flex::Configuration.config_file properly' \
|
92
|
-
unless File.exist?(@indices_yaml)
|
93
|
-
Manager.indices(@indices_yaml)
|
94
|
-
end
|
95
|
-
end
|
96
|
-
|
97
|
-
|
98
|
-
def models
|
99
|
-
@models ||= begin
|
100
|
-
mods = ENV['MODELS'] || Flex::Configuration.flex_models
|
101
|
-
raise AgrumentError, 'no class defined. Please use MODELS=[ClassA,ClassB]' +
|
102
|
-
'or set the Flex::Configuration.flex_models properly' \
|
103
|
-
if mods.nil? || mods.empty?
|
104
|
-
mods = eval(mods) if mods.is_a?(String)
|
105
|
-
mods = [mods] unless mods.is_a?(Array)
|
106
|
-
mods.map{|c| c.is_a?(String) ? eval("::#{c}") : c}
|
107
|
-
end
|
47
|
+
def config_path
|
48
|
+
@config_path ||= options[:config_file] || Conf.config_file
|
108
49
|
end
|
109
50
|
|
110
51
|
def delete_index(index)
|
@@ -112,9 +53,8 @@ module Flex
|
|
112
53
|
end
|
113
54
|
|
114
55
|
def create(index)
|
115
|
-
|
116
|
-
|
117
|
-
Flex.POST "/#{index}", struct[index]
|
56
|
+
config_hash[index] = {} unless config_hash.has_key?(index)
|
57
|
+
Flex.POST "/#{index}", config_hash[index]
|
118
58
|
end
|
119
59
|
|
120
60
|
end
|
data/lib/flex/template.rb
CHANGED
@@ -7,84 +7,85 @@ module Flex
|
|
7
7
|
# For more details about templates, see the documentation.
|
8
8
|
class Template
|
9
9
|
|
10
|
-
include
|
10
|
+
include Logger
|
11
|
+
include Common
|
11
12
|
|
12
13
|
def self.variables
|
13
|
-
|
14
|
+
Vars.new
|
14
15
|
end
|
15
16
|
|
16
|
-
attr_reader :method, :path
|
17
|
+
attr_reader :method, :path
|
17
18
|
|
18
|
-
def initialize(method, path, data=nil, vars
|
19
|
+
def initialize(method, path, data=nil, *vars)
|
19
20
|
@method = method.to_s.upcase
|
20
21
|
raise ArgumentError, "#@method method not supported" \
|
21
22
|
unless %w[HEAD GET PUT POST DELETE].include?(@method)
|
22
23
|
@path = path =~ /^\// ? path : "/#{path}"
|
23
|
-
@data = Utils.
|
24
|
-
@instance_vars = vars
|
24
|
+
@data = Utils.parse_source(data)
|
25
|
+
@instance_vars = Vars.new(*vars)
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
30
|
-
@source_vars = source_vars
|
31
|
-
self
|
32
|
-
end
|
33
|
-
|
34
|
-
def render(vars={})
|
35
|
-
do_render(vars) do |response, int|
|
36
|
-
Result.new(self, int[:vars], response)
|
28
|
+
def render(*vars)
|
29
|
+
do_render(*vars) do |response, int|
|
30
|
+
Result.new(self, int[:vars], response).to_flex_result
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
40
|
-
def to_a(vars
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
def to_a(*vars)
|
35
|
+
vars = Vars.new(*vars)
|
36
|
+
int = interpolate(vars)
|
37
|
+
a = [method, int[:path], Utils.keyfy(:to_s, int[:data]), Utils.keyfy(:to_s, @instance_vars)]
|
38
|
+
2.times { a.pop if a.last.nil? || a.last.empty? }
|
44
39
|
a
|
45
40
|
end
|
46
41
|
|
47
|
-
def
|
48
|
-
|
42
|
+
def to_source
|
43
|
+
{@name.to_s => to_a}.to_yaml
|
49
44
|
end
|
50
45
|
|
51
|
-
def to_flex(name=nil)
|
52
|
-
(name ? {name.to_s => to_a} : to_a).to_yaml
|
53
|
-
end
|
54
46
|
|
55
47
|
private
|
56
48
|
|
57
|
-
def do_render(vars
|
58
|
-
|
59
|
-
path
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
# used in Flex.exist?
|
64
|
-
return response.status == 200 if method == 'HEAD'
|
65
|
-
|
66
|
-
if Configuration.raise_proc.call(response)
|
49
|
+
def do_render(*vars)
|
50
|
+
vars = Vars.new(*vars)
|
51
|
+
int, path, encoded_data, response = try_clean_and_retry(vars)
|
52
|
+
return response.status == 200 if method == 'HEAD' # used in Flex.exist?
|
53
|
+
if Conf.http_client.raise_proc.call(response)
|
67
54
|
int[:vars][:raise].is_a?(FalseClass) ? return : raise(HttpError.new(response, caller_line))
|
68
55
|
end
|
69
|
-
|
70
56
|
result = yield(response, int)
|
71
|
-
|
72
|
-
rescue NameError => e
|
73
|
-
if e.name == :request
|
74
|
-
raise MissingHttpClientError,
|
75
|
-
'you should install the gem "patron" (recommended for performances) or "rest-client", ' +
|
76
|
-
'or provide your own http-client interface and set Flex::Configuration.http_client'
|
77
|
-
else
|
78
|
-
raise
|
79
|
-
end
|
80
57
|
ensure
|
81
|
-
|
58
|
+
log_render(int, path, encoded_data, result)
|
59
|
+
result
|
60
|
+
end
|
61
|
+
|
62
|
+
# This allows to use Lucene style search language in the :cleanable_query declared variable and
|
63
|
+
# in case of a syntax error it will remove all the problematic characters and retry with a cleaned query_string
|
64
|
+
# http://lucene.apache.org/core/old_versioned_docs/versions/3_5_0/queryparsersyntax.html
|
65
|
+
def try_clean_and_retry(vars)
|
66
|
+
response_vars = request(vars)
|
67
|
+
if !Prunable::VALUES.include?(vars[:cleanable_query]) && Conf.http_client.raise_proc.call(response_vars[3])
|
68
|
+
e = HttpError.new(response_vars[3], caller_line)
|
69
|
+
e.to_hash['error'] =~ /^SearchPhaseExecutionException/
|
70
|
+
(vars[:cleanable_query].is_a?(String) ? vars[:cleanable_query] : vars[:cleanable_query][:query]).tr!('"&|!(){}[]~^:+-\\', '')
|
71
|
+
request vars
|
72
|
+
else
|
73
|
+
response_vars
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def request(vars)
|
78
|
+
int = interpolate(vars, strict=true)
|
79
|
+
path = build_path(int, vars)
|
80
|
+
encoded_data = build_data(int, vars)
|
81
|
+
response = Conf.http_client.request(method, path, encoded_data)
|
82
|
+
return int, path, encoded_data, response
|
82
83
|
end
|
83
84
|
|
84
85
|
def build_path(int, vars)
|
85
86
|
params = int[:vars][:params]
|
86
87
|
path = vars[:path] || int[:path]
|
87
|
-
|
88
|
+
unless params.empty?
|
88
89
|
path << ((path =~ /\?/) ? '&' : '?')
|
89
90
|
path << params.map { |p| p.join('=') }.join('&')
|
90
91
|
end
|
@@ -92,60 +93,25 @@ module Flex
|
|
92
93
|
end
|
93
94
|
|
94
95
|
def build_data(int, vars)
|
95
|
-
data = vars[:data] && Utils.
|
96
|
+
data = vars[:data] && Utils.parse_source(vars[:data]) || int[:data]
|
96
97
|
(data.nil? || data.is_a?(String)) ? data : MultiJson.encode(data)
|
97
98
|
end
|
98
99
|
|
99
|
-
def to_logger(path, encoded_data, result)
|
100
|
-
h = {}
|
101
|
-
h[:method] = method
|
102
|
-
h[:path] = path
|
103
|
-
h[:data] = MultiJson.decode(encoded_data) unless encoded_data.nil?
|
104
|
-
h[:result] = result if result && Configuration.debug_result
|
105
|
-
log = Configuration.debug_to_curl ? to_curl_string(h) : Utils.stringified_hash(h).to_yaml
|
106
|
-
Configuration.logger.debug "[FLEX] Rendered #{caller_line}\n#{log}"
|
107
|
-
end
|
108
|
-
|
109
|
-
def caller_line
|
110
|
-
method_name = @host_flex && @name && "#{@host_flex.host_class}.#@name"
|
111
|
-
line = caller.find{|l| l !~ /#{LIB_PATH}/}
|
112
|
-
ll = ''
|
113
|
-
ll << "#{method_name} from " if method_name
|
114
|
-
ll << "#{line}"
|
115
|
-
ll
|
116
|
-
end
|
117
|
-
|
118
|
-
def to_curl_string(h)
|
119
|
-
pretty = h[:path] =~ /\?/ ? '&pretty=1' : '?pretty=1'
|
120
|
-
curl = %(curl -X#{method} "#{Configuration.base_uri}#{h[:path]}#{pretty}")
|
121
|
-
if h[:data]
|
122
|
-
data = if h[:data].is_a?(String)
|
123
|
-
h[:data].length > 1024 ? h[:data][0,1024] + '...(truncated display)' : h[:data]
|
124
|
-
else
|
125
|
-
MultiJson.encode(h[:data], :pretty => true)
|
126
|
-
end
|
127
|
-
curl << %( -d '\n#{data}\n')
|
128
|
-
end
|
129
|
-
curl
|
130
|
-
end
|
131
|
-
|
132
100
|
def interpolate(*args)
|
133
|
-
tags
|
134
|
-
stringified
|
135
|
-
@partials, @tags = tags.
|
136
|
-
@
|
137
|
-
@
|
138
|
-
@variables.add(@host_flex.variables) if @host_flex
|
139
|
-
@variables.add(@source_vars, @instance_vars, tags.variables)
|
101
|
+
tags = Tags.new
|
102
|
+
stringified = tags.stringify(:path => @path, :data => @data)
|
103
|
+
@partials, @tags = tags.partial_and_tag_names
|
104
|
+
@base_variables = Conf.variables.deep_merge(self.class.variables)
|
105
|
+
@temp_variables = Vars.new(@source_vars, @instance_vars, tags.variables)
|
140
106
|
instance_eval <<-ruby, __FILE__, __LINE__
|
141
107
|
def interpolate(vars={}, strict=false)
|
108
|
+
vars = Vars.new(vars) unless vars.is_a?(Flex::Vars)
|
142
109
|
return {:path => path, :data => data, :vars => vars} if vars.empty? && !strict
|
143
|
-
|
144
|
-
vars
|
145
|
-
|
146
|
-
|
147
|
-
obj
|
148
|
-
obj = prune(obj)
|
110
|
+
context_variables = vars[:context] ? vars[:context].flex.variables : (@host_flex && @host_flex.variables)
|
111
|
+
vars = @base_variables.deep_merge(context_variables, @temp_variables, vars).finalize
|
112
|
+
vars = interpolate_partials(vars)
|
113
|
+
obj = #{stringified}
|
114
|
+
obj = Prunable.prune(obj, Prunable::Value)
|
149
115
|
obj[:path].tr_s!('/', '/') # removes empty path segments
|
150
116
|
obj[:vars] = vars
|
151
117
|
obj
|
@@ -154,31 +120,5 @@ module Flex
|
|
154
120
|
interpolate(*args)
|
155
121
|
end
|
156
122
|
|
157
|
-
# prunes the branch when the leaf is a PrunableObject
|
158
|
-
# and compact.flatten the Array values
|
159
|
-
def prune(obj)
|
160
|
-
case obj
|
161
|
-
when Array
|
162
|
-
return if obj.is_a?(PrunableObject)
|
163
|
-
a = obj.map do |i|
|
164
|
-
next if i.is_a?(PrunableObject)
|
165
|
-
prune(i)
|
166
|
-
end.compact.flatten
|
167
|
-
a unless a.empty?
|
168
|
-
when Hash
|
169
|
-
return if obj.is_a?(PrunableObject)
|
170
|
-
return obj if obj.empty?
|
171
|
-
h = {}
|
172
|
-
obj.each do |k, v|
|
173
|
-
pruned = prune(v)
|
174
|
-
next if pruned.is_a?(PrunableObject)
|
175
|
-
h[k] = pruned
|
176
|
-
end
|
177
|
-
h unless h.empty?
|
178
|
-
else
|
179
|
-
obj
|
180
|
-
end
|
181
|
-
end
|
182
|
-
|
183
123
|
end
|
184
124
|
end
|