flex 0.4.2 → 1.0.1
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/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
|