locomotivecms_steam 1.0.0.rc6 → 1.0.0.rc8
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gemfile.lock +21 -19
- data/lib/locomotive/steam/adapters/filesystem/sanitizers/content_entry.rb +1 -1
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/content_type.rb +3 -2
- data/lib/locomotive/steam/adapters/filesystem/yaml_loaders/page.rb +12 -4
- data/lib/locomotive/steam/adapters/memory/condition.rb +2 -2
- data/lib/locomotive/steam/adapters/memory/order.rb +5 -0
- data/lib/locomotive/steam/entities/content_entry.rb +1 -1
- data/lib/locomotive/steam/entities/editable_element.rb +1 -4
- data/lib/locomotive/steam/liquid/drops/page.rb +36 -16
- data/lib/locomotive/steam/liquid/tags/editable/base.rb +25 -1
- data/lib/locomotive/steam/liquid/tags/editable/model.rb +4 -0
- data/lib/locomotive/steam/liquid/tags/editable/text.rb +5 -1
- data/lib/locomotive/steam/liquid/tags/extends.rb +11 -0
- data/lib/locomotive/steam/liquid/tags/with_scope.rb +11 -9
- data/lib/locomotive/steam/liquid/template.rb +33 -0
- data/lib/locomotive/steam/middlewares/templatized_page.rb +11 -6
- data/lib/locomotive/steam/models/mapper.rb +4 -0
- data/lib/locomotive/steam/models/repository.rb +1 -0
- data/lib/locomotive/steam/repositories/content_entry_repository.rb +37 -29
- data/lib/locomotive/steam/repositories/content_type_field_repository.rb +4 -0
- data/lib/locomotive/steam/repositories/page_repository.rb +2 -2
- data/lib/locomotive/steam/services/liquid_parser_service.rb +6 -5
- data/lib/locomotive/steam/version.rb +1 -1
- data/locomotivecms_steam.gemspec +1 -0
- data/spec/integration/liquid/drops/page_spec.rb +43 -0
- data/spec/support/liquid.rb +1 -1
- data/spec/unit/adapters/filesystem/yaml_loaders/content_type_spec.rb +21 -0
- data/spec/unit/adapters/memory/condition_spec.rb +9 -1
- data/spec/unit/adapters/memory/order_spec.rb +9 -0
- data/spec/unit/entities/content_entry_spec.rb +3 -3
- data/spec/unit/liquid/drops/page_spec.rb +1 -1
- data/spec/unit/liquid/tags/editable/text_spec.rb +23 -4
- data/spec/unit/liquid/tags/extends_spec.rb +19 -1
- data/spec/unit/liquid/tags/inherited_block_spec.rb +1 -1
- data/spec/unit/liquid/tags/with_scope_spec.rb +21 -0
- data/spec/unit/repositories/content_entry_repository_spec.rb +74 -4
- data/spec/unit/repositories/page_repository_spec.rb +6 -0
- metadata +19 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 193721014cf846cba6f95200c9d8f4d9d40e82fb
|
4
|
+
data.tar.gz: 1a0121ad4705b29db57e30535fb15c7725904805
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e3930c146bea95ec4aa7c60802020e0ea2d6e485693bbd417b25cb6d80dc21fa0ec54c64e59974de0f0529a089e6d1da7ccb2ba96f6cef869c4e33c856753b53
|
7
|
+
data.tar.gz: 0b4f8ff10324d481564b9807fb02c2b6188b25d25049ec4eb592315398dd00184aea9003c01181a4b625804a9b3f6a50c1bd4a3458f4a43a9cb327596d67038f
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
locomotivecms_steam (1.0.0.
|
4
|
+
locomotivecms_steam (1.0.0.rc8)
|
5
5
|
RedCloth (~> 4.2.9)
|
6
6
|
chronic (~> 0.10.2)
|
7
7
|
coffee-script (~> 2.4.1)
|
@@ -17,6 +17,7 @@ PATH
|
|
17
17
|
moneta (~> 0.8.0)
|
18
18
|
mongo (~> 2.1.2)
|
19
19
|
morphine (~> 0.1.1)
|
20
|
+
nokogiri (~> 1.6.6.4)
|
20
21
|
origin (~> 2.1.1)
|
21
22
|
rack-cache (~> 1.2)
|
22
23
|
rack-rewrite (~> 1.5.1)
|
@@ -43,7 +44,7 @@ GEM
|
|
43
44
|
columnize (= 0.9.0)
|
44
45
|
chronic (0.10.2)
|
45
46
|
chunky_png (1.3.5)
|
46
|
-
codeclimate-test-reporter (0.4.
|
47
|
+
codeclimate-test-reporter (0.4.8)
|
47
48
|
simplecov (>= 0.7.1, < 1.0.0)
|
48
49
|
coderay (1.1.0)
|
49
50
|
coffee-script (2.4.1)
|
@@ -65,16 +66,17 @@ GEM
|
|
65
66
|
sass (>= 3.3.0, < 3.5)
|
66
67
|
compass-import-once (1.0.5)
|
67
68
|
sass (>= 3.2, < 3.5)
|
68
|
-
coveralls (0.8.
|
69
|
+
coveralls (0.8.10)
|
69
70
|
json (~> 1.8)
|
70
71
|
rest-client (>= 1.6.8, < 2)
|
71
|
-
simplecov (~> 0.
|
72
|
+
simplecov (~> 0.11.0)
|
72
73
|
term-ansicolor (~> 1.3)
|
73
74
|
thor (~> 0.19.1)
|
75
|
+
tins (~> 1.6.0)
|
74
76
|
crass (1.0.2)
|
75
77
|
diff-lcs (1.2.5)
|
76
78
|
docile (1.1.5)
|
77
|
-
domain_name (0.5.
|
79
|
+
domain_name (0.5.25)
|
78
80
|
unf (>= 0.0.5, < 1.0.0)
|
79
81
|
dragonfly (1.0.12)
|
80
82
|
addressable (~> 2.3)
|
@@ -115,9 +117,9 @@ GEM
|
|
115
117
|
attr_extras (~> 4.4.0)
|
116
118
|
colorize
|
117
119
|
stringex (~> 2.5.2)
|
118
|
-
memory_profiler (0.9.
|
120
|
+
memory_profiler (0.9.6)
|
119
121
|
method_source (0.8.2)
|
120
|
-
mime-types (2.6.
|
122
|
+
mime-types (2.6.2)
|
121
123
|
mimetype-fu (0.1.2)
|
122
124
|
mini_portile (0.6.2)
|
123
125
|
minitest (5.8.3)
|
@@ -125,26 +127,26 @@ GEM
|
|
125
127
|
mongo (2.1.2)
|
126
128
|
bson (~> 3.0)
|
127
129
|
morphine (0.1.1)
|
128
|
-
multi_json (1.11.
|
130
|
+
multi_json (1.11.2)
|
129
131
|
multi_xml (0.5.5)
|
130
|
-
netrc (0.
|
132
|
+
netrc (0.11.0)
|
131
133
|
nokogiri (1.6.6.4)
|
132
134
|
mini_portile (~> 0.6.0)
|
133
135
|
nokogumbo (1.4.1)
|
134
136
|
nokogiri
|
135
137
|
origin (2.1.1)
|
136
|
-
pry (0.10.
|
138
|
+
pry (0.10.3)
|
137
139
|
coderay (~> 1.1.0)
|
138
140
|
method_source (~> 0.8.1)
|
139
141
|
slop (~> 3.4)
|
140
142
|
pry-byebug (3.1.0)
|
141
143
|
byebug (~> 4.0)
|
142
144
|
pry (~> 0.10)
|
143
|
-
puma (2.
|
144
|
-
rack (1.6.
|
145
|
+
puma (2.15.3)
|
146
|
+
rack (1.6.4)
|
145
147
|
rack-cache (1.5.1)
|
146
148
|
rack (>= 0.4)
|
147
|
-
rack-mini-profiler (0.9.
|
149
|
+
rack-mini-profiler (0.9.8)
|
148
150
|
rack (>= 1.1.3)
|
149
151
|
rack-rewrite (1.5.1)
|
150
152
|
rack-test (0.6.3)
|
@@ -165,12 +167,12 @@ GEM
|
|
165
167
|
rspec-core (~> 3.3.0)
|
166
168
|
rspec-expectations (~> 3.3.0)
|
167
169
|
rspec-mocks (~> 3.3.0)
|
168
|
-
rspec-core (3.3.
|
170
|
+
rspec-core (3.3.2)
|
169
171
|
rspec-support (~> 3.3.0)
|
170
|
-
rspec-expectations (3.3.
|
172
|
+
rspec-expectations (3.3.1)
|
171
173
|
diff-lcs (>= 1.2.0, < 2.0)
|
172
174
|
rspec-support (~> 3.3.0)
|
173
|
-
rspec-mocks (3.3.
|
175
|
+
rspec-mocks (3.3.2)
|
174
176
|
diff-lcs (>= 1.2.0, < 2.0)
|
175
177
|
rspec-support (~> 3.3.0)
|
176
178
|
rspec-support (3.3.0)
|
@@ -179,7 +181,7 @@ GEM
|
|
179
181
|
nokogiri (>= 1.4.4)
|
180
182
|
nokogumbo (= 1.4.1)
|
181
183
|
sass (3.4.19)
|
182
|
-
simplecov (0.
|
184
|
+
simplecov (0.11.1)
|
183
185
|
docile (~> 1.1.0)
|
184
186
|
json (~> 1.8)
|
185
187
|
simplecov-html (~> 0.10.0)
|
@@ -198,13 +200,13 @@ GEM
|
|
198
200
|
tilt (~> 1.1)
|
199
201
|
stackprof (0.2.7)
|
200
202
|
stringex (2.5.2)
|
201
|
-
term-ansicolor (1.3.
|
203
|
+
term-ansicolor (1.3.2)
|
202
204
|
tins (~> 1.0)
|
203
205
|
thor (0.19.1)
|
204
206
|
thread_safe (0.3.5)
|
205
207
|
tilt (1.4.1)
|
206
208
|
timecop (0.7.4)
|
207
|
-
tins (1.
|
209
|
+
tins (1.6.0)
|
208
210
|
tzinfo (1.2.2)
|
209
211
|
thread_safe (~> 0.1)
|
210
212
|
unf (0.1.4)
|
@@ -57,7 +57,7 @@ module Locomotive::Steam
|
|
57
57
|
entity._label.each do |locale, label|
|
58
58
|
entity[:_slug][locale] ||= slugify(entity._id, label, dataset, locale)
|
59
59
|
end
|
60
|
-
|
60
|
+
elsif entity[:_slug] && entity[:_slug][:anylocale].nil?
|
61
61
|
# Note: replace the translations of the I18nField by a string
|
62
62
|
entity[:_slug].translations = slugify(entity._id, entity._label, dataset)
|
63
63
|
end
|
@@ -66,7 +66,7 @@ module Locomotive
|
|
66
66
|
if (option = list.at(position)).nil?
|
67
67
|
list << { _id: name, name: { locale => name }, position: position }
|
68
68
|
else
|
69
|
-
option[name][locale] = name
|
69
|
+
option[:name][locale] = name
|
70
70
|
end
|
71
71
|
end
|
72
72
|
end
|
@@ -76,7 +76,8 @@ module Locomotive
|
|
76
76
|
def build_select_options_from_array(options)
|
77
77
|
[].tap do |list|
|
78
78
|
options.each_with_index do |name, position|
|
79
|
-
|
79
|
+
_id = name.is_a?(Hash) ? name.values.first : name
|
80
|
+
list << { _id: _id, name: name, position: position }
|
80
81
|
end
|
81
82
|
end
|
82
83
|
end
|
@@ -42,14 +42,19 @@ module Locomotive
|
|
42
42
|
slug = fullpath.split('/').last
|
43
43
|
attributes = get_attributes(filepath, fullpath)
|
44
44
|
|
45
|
-
{
|
45
|
+
_attributes = {
|
46
46
|
title: { locale => attributes.delete(:title) || (default_locale == locale ? slug.humanize : nil) },
|
47
47
|
slug: { locale => attributes.delete(:slug) || slug.dasherize },
|
48
48
|
template_path: { locale => template_path(filepath, attributes, locale) },
|
49
|
-
redirect_url: { locale => attributes.delete(:redirect_url) },
|
50
49
|
editable_elements: build_editable_elements(attributes.delete(:editable_elements), locale),
|
51
50
|
_fullpath: fullpath
|
52
|
-
}
|
51
|
+
}
|
52
|
+
|
53
|
+
[:redirect_url, :seo_title, :meta_description, :meta_keywords].each do |name|
|
54
|
+
_attributes[name] = { locale => attributes.delete(name) }
|
55
|
+
end
|
56
|
+
|
57
|
+
_attributes.merge!(attributes)
|
53
58
|
end
|
54
59
|
|
55
60
|
def update(leaf, filepath, fullpath, locale)
|
@@ -59,7 +64,10 @@ module Locomotive
|
|
59
64
|
leaf[:title][locale] = attributes.delete(:title) || slug.humanize
|
60
65
|
leaf[:slug][locale] = attributes.delete(:slug) || slug.dasherize
|
61
66
|
leaf[:template_path][locale] = template_path(filepath, attributes, locale)
|
62
|
-
|
67
|
+
|
68
|
+
[:redirect_url, :seo_title, :meta_description, :meta_keywords].each do |name|
|
69
|
+
leaf[name][locale] = attributes.delete(name)
|
70
|
+
end
|
63
71
|
|
64
72
|
update_editable_elements(leaf, attributes.delete(:editable_elements), locale)
|
65
73
|
|
@@ -41,7 +41,7 @@ module Locomotive::Steam
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def inspect
|
44
|
-
"#{field}
|
44
|
+
"#{field}#{operator != :== ? '.' : ' '}#{operator} #{value}"
|
45
45
|
end
|
46
46
|
|
47
47
|
protected
|
@@ -92,7 +92,7 @@ module Locomotive::Steam
|
|
92
92
|
if target.size == 0
|
93
93
|
source.size == 0
|
94
94
|
else
|
95
|
-
source & target
|
95
|
+
(source & target).size != 0
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
@@ -25,6 +25,11 @@ module Locomotive::Steam
|
|
25
25
|
def apply_to(entry, locale)
|
26
26
|
@list.collect do |(name, direction)|
|
27
27
|
value = entry.send(name)
|
28
|
+
|
29
|
+
if value.respond_to?(:translations) # localized
|
30
|
+
value = value[locale]
|
31
|
+
end
|
32
|
+
|
28
33
|
asc?(direction) ? Asc.new(value) : Desc.new(value)
|
29
34
|
end
|
30
35
|
end
|
@@ -8,6 +8,7 @@ module Locomotive::Steam
|
|
8
8
|
|
9
9
|
def initialize(attributes = {})
|
10
10
|
super({
|
11
|
+
label: nil,
|
11
12
|
block: nil,
|
12
13
|
content: nil,
|
13
14
|
source: nil,
|
@@ -23,10 +24,6 @@ module Locomotive::Steam
|
|
23
24
|
self[:format] || 'html' # only editable_text elements
|
24
25
|
end
|
25
26
|
|
26
|
-
def default_content?
|
27
|
-
self.content.blank?
|
28
|
-
end
|
29
|
-
|
30
27
|
end
|
31
28
|
|
32
29
|
end
|
@@ -62,32 +62,52 @@ module Locomotive
|
|
62
62
|
end
|
63
63
|
|
64
64
|
def build_editable_elements_hash
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
keys = el.block.try(:split, '/').try(:compact) || []
|
65
|
+
{}.tap do |hash|
|
66
|
+
# default content from the template itself
|
67
|
+
_build_default_editable_elements_hash(hash)
|
69
68
|
|
70
|
-
|
69
|
+
# content updated by the users
|
70
|
+
_build_editable_elements_hash(hash)
|
71
|
+
end
|
72
|
+
end
|
71
73
|
|
72
|
-
|
73
|
-
|
74
|
-
|
74
|
+
def _build_default_editable_elements_hash(hash)
|
75
|
+
(@context.registers[:default_editable_content] || []).each do |key, content|
|
76
|
+
keys = key.split('/')
|
77
|
+
_build_editable_elements_hashes(hash, keys, keys.pop, content)
|
75
78
|
end
|
79
|
+
end
|
76
80
|
|
77
|
-
|
78
|
-
|
81
|
+
def _build_editable_elements_hash(hash)
|
82
|
+
(repository.editable_elements_of(@_source) || []).each do |el|
|
83
|
+
keys = el.block.try(:split, '/').try(:compact) || []
|
79
84
|
|
80
|
-
|
81
|
-
|
85
|
+
# decorate the el instance which is localized because
|
86
|
+
# el.content returns a I18nField.
|
87
|
+
content = editable_element_content(el)
|
82
88
|
|
83
|
-
|
89
|
+
_build_editable_elements_hashes(hash, keys, el.slug, content)
|
90
|
+
end
|
91
|
+
end
|
84
92
|
|
85
|
-
|
86
|
-
|
93
|
+
def editable_element_content(element)
|
94
|
+
Locomotive::Steam::Decorators::I18nDecorator.new(element,
|
95
|
+
@_source.__locale__,
|
96
|
+
@_source.__default_locale__).content
|
97
|
+
end
|
98
|
+
|
99
|
+
def _build_editable_elements_hashes(hash, keys, slug, content)
|
100
|
+
last_hash = hash
|
87
101
|
|
88
|
-
|
102
|
+
# go the last hash
|
103
|
+
keys.each do |key|
|
104
|
+
safe_key = key.parameterize.underscore
|
105
|
+
last_hash = (last_hash[safe_key] ||= {})
|
89
106
|
end
|
90
107
|
|
108
|
+
last_hash[slug.parameterize.underscore] = content
|
109
|
+
end
|
110
|
+
|
91
111
|
end
|
92
112
|
end
|
93
113
|
end
|
@@ -12,9 +12,11 @@ module Locomotive
|
|
12
12
|
def initialize(tag_name, markup, options)
|
13
13
|
if markup =~ Syntax
|
14
14
|
@page_fullpath = options[:page].fullpath
|
15
|
-
@
|
15
|
+
@label_or_slug = $1.gsub(/[\"\']/, '')
|
16
16
|
@element_options = { fixed: false, inline_editing: true }
|
17
17
|
markup.scan(::Liquid::TagAttributes) { |key, value| @element_options[key.to_sym] = value.gsub(/^[\"\']/, '').gsub(/[\"\']$/, '') }
|
18
|
+
|
19
|
+
self.set_label_and_slug
|
18
20
|
else
|
19
21
|
raise ::Liquid::SyntaxError.new("Valid syntax: #{tag_name} <slug>(, <options>)")
|
20
22
|
end
|
@@ -25,6 +27,8 @@ module Locomotive
|
|
25
27
|
def parse(tokens)
|
26
28
|
super.tap do
|
27
29
|
ActiveSupport::Notifications.instrument("steam.parse.editable.#{@tag_name}", page: options[:page], attributes: default_element_attributes)
|
30
|
+
|
31
|
+
register_default_content
|
28
32
|
end
|
29
33
|
end
|
30
34
|
|
@@ -56,9 +60,29 @@ module Locomotive
|
|
56
60
|
pages[@page_fullpath] ||= service.find(@page_fullpath)
|
57
61
|
end
|
58
62
|
|
63
|
+
def register_default_content
|
64
|
+
return if options[:default_editable_content].nil?
|
65
|
+
|
66
|
+
hash = options[:default_editable_content]
|
67
|
+
key = [current_inherited_block_name, @slug].compact.join('/')
|
68
|
+
|
69
|
+
hash[key] = render_default_content
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_label_and_slug
|
73
|
+
@slug = @label_or_slug
|
74
|
+
@label = @element_options[:label]
|
75
|
+
|
76
|
+
if @element_options[:slug].present?
|
77
|
+
@slug = @element_options[:slug]
|
78
|
+
@label ||= @label_or_slug
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
59
82
|
def default_element_attributes
|
60
83
|
{
|
61
84
|
block: self.current_inherited_block_name,
|
85
|
+
label: @label,
|
62
86
|
slug: @slug,
|
63
87
|
hint: @element_options[:hint],
|
64
88
|
priority: @element_options[:priority] || 0,
|
@@ -9,7 +9,7 @@ module Locomotive
|
|
9
9
|
|
10
10
|
def render_element(context, element)
|
11
11
|
with_inline_editing(context, element) do
|
12
|
-
content = if
|
12
|
+
content = if default_content?(element)
|
13
13
|
render_default_content
|
14
14
|
else
|
15
15
|
element.content
|
@@ -39,6 +39,10 @@ module Locomotive
|
|
39
39
|
!!context.registers[:live_editing] && element.inline_editing
|
40
40
|
end
|
41
41
|
|
42
|
+
def default_content?(element)
|
43
|
+
element.content.blank?
|
44
|
+
end
|
45
|
+
|
42
46
|
def default_element_attributes
|
43
47
|
super.merge(
|
44
48
|
content_from_default: self.render_default_content,
|
@@ -4,6 +4,13 @@ module Locomotive
|
|
4
4
|
module Tags
|
5
5
|
class Extends < ::Liquid::Extends
|
6
6
|
|
7
|
+
def render(context)
|
8
|
+
context.stack do
|
9
|
+
context['layout_name'] = @layout_name
|
10
|
+
super
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
7
14
|
private
|
8
15
|
|
9
16
|
def parse_parent_template
|
@@ -14,6 +21,10 @@ module Locomotive
|
|
14
21
|
|
15
22
|
ActiveSupport::Notifications.instrument('steam.parse.extends', page: options[:page], parent: parent)
|
16
23
|
|
24
|
+
# define the layout name which is basically the handle of the parent page
|
25
|
+
# if there is no handle, we take the slug which might or might not be localized.
|
26
|
+
@layout_name = parent.handle || parent.slug
|
27
|
+
|
17
28
|
# the source has already been parsed before
|
18
29
|
options[:parser]._parse(parent, options.merge(page: parent))
|
19
30
|
end
|
@@ -45,18 +45,20 @@ module Locomotive
|
|
45
45
|
# _slug instead of _permalink
|
46
46
|
_key = key.to_s == '_permalink' ? '_slug' : key.to_s
|
47
47
|
|
48
|
-
hash[_key] = (
|
49
|
-
# regexp inside a string
|
50
|
-
when /^\/[^\/]*\/$/ then Regexp.new(value[1..-2])
|
51
|
-
# content entry drop? Use the source (entity) instead
|
52
|
-
when Locomotive::Steam::Liquid::Drops::ContentEntry
|
53
|
-
value.send(:_source)
|
54
|
-
else
|
55
|
-
value
|
56
|
-
end)
|
48
|
+
hash[_key] = cast_value(value)
|
57
49
|
end
|
58
50
|
end
|
59
51
|
end
|
52
|
+
|
53
|
+
def cast_value(value)
|
54
|
+
case value
|
55
|
+
when Array then value.map { |_value| cast_value(_value) }
|
56
|
+
when /^\/[^\/]*\/$/ then Regexp.new(value[1..-2])
|
57
|
+
else
|
58
|
+
value.respond_to?(:_id) ? value.send(:_source) : value
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
60
62
|
end
|
61
63
|
|
62
64
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Locomotive
|
2
|
+
module Steam
|
3
|
+
module Liquid
|
4
|
+
|
5
|
+
class Template < ::Liquid::Template
|
6
|
+
|
7
|
+
# When we render a Locomotive template, we need to know what are
|
8
|
+
# the default content of all the editable elements.
|
9
|
+
# Without this, developers are unable to use statements like
|
10
|
+
# the following: {{ page.editable_elements.content.header.title }}
|
11
|
+
def render(*args)
|
12
|
+
if args.first && args.first.is_a?(::Liquid::Context)
|
13
|
+
content = @options[:default_editable_content]
|
14
|
+
args.first.registers[:default_editable_content] = content
|
15
|
+
end
|
16
|
+
|
17
|
+
super
|
18
|
+
end
|
19
|
+
|
20
|
+
class << self
|
21
|
+
|
22
|
+
def parse(source, options = {})
|
23
|
+
template = new
|
24
|
+
template.parse(source, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -28,7 +28,8 @@ module Locomotive::Steam
|
|
28
28
|
# log it
|
29
29
|
log "Found content entry: #{entry._label}"
|
30
30
|
else
|
31
|
-
|
31
|
+
url = services.url_builder.url_for(page_not_found, locale)
|
32
|
+
redirect_to url, 302
|
32
33
|
end
|
33
34
|
end
|
34
35
|
|
@@ -40,11 +41,6 @@ module Locomotive::Steam
|
|
40
41
|
end
|
41
42
|
end
|
42
43
|
|
43
|
-
def decorate(entry)
|
44
|
-
return nil if entry.nil?
|
45
|
-
Locomotive::Steam::Decorators::I18nDecorator.new(entry, locale, default_locale)
|
46
|
-
end
|
47
|
-
|
48
44
|
def content_type_repository
|
49
45
|
services.repositories.content_type
|
50
46
|
end
|
@@ -53,6 +49,15 @@ module Locomotive::Steam
|
|
53
49
|
services.repositories.content_entry
|
54
50
|
end
|
55
51
|
|
52
|
+
def page_not_found
|
53
|
+
services.page_finder.find('404')
|
54
|
+
end
|
55
|
+
|
56
|
+
def decorate(entry)
|
57
|
+
return nil if entry.nil?
|
58
|
+
Locomotive::Steam::Decorators::I18nDecorator.new(entry, locale, default_locale)
|
59
|
+
end
|
60
|
+
|
56
61
|
end
|
57
62
|
end
|
58
63
|
end
|
@@ -130,33 +130,11 @@ module Locomotive
|
|
130
130
|
end
|
131
131
|
|
132
132
|
def prepare_conditions(*conditions)
|
133
|
-
# _conditions = conditions.first.try(:with_indifferent_access)
|
134
|
-
|
135
133
|
_conditions = Conditions.new(conditions.first, self.content_type.fields).prepare
|
136
134
|
|
137
135
|
super({ _visible: true }, _conditions)
|
138
136
|
end
|
139
137
|
|
140
|
-
# # belongs_to fields? if so, make sure we use the _id and we deal with the ID, not the object itself
|
141
|
-
# def prepare_conditions_for_belongs_to_fields(conditions)
|
142
|
-
# self.content_type.fields.belongs_to.each do |field|
|
143
|
-
# if value = conditions[name = field.name.to_s]
|
144
|
-
# conditions.delete(name)
|
145
|
-
# conditions[name + '_id'] = value.try(:_id)
|
146
|
-
# end
|
147
|
-
# end
|
148
|
-
# end
|
149
|
-
|
150
|
-
# # select fields? if so, use the _id of the option instead of the option name
|
151
|
-
# def prepare_conditions_for_select_fields(conditions)
|
152
|
-
# self.content_type.fields.selects.each do |field|
|
153
|
-
# if value = conditions[name = field.name.to_s]
|
154
|
-
# conditions.delete(name)
|
155
|
-
# conditions[name + '_id'] = field.select_options.by_name(value).try(:_id)
|
156
|
-
# end
|
157
|
-
# end
|
158
|
-
# end
|
159
|
-
|
160
138
|
def add_localized_fields_to_mapper(mapper)
|
161
139
|
unless self.content_type.localized_names.blank?
|
162
140
|
mapper.localized_attributes(*self.content_type.localized_names)
|
@@ -207,17 +185,25 @@ module Locomotive
|
|
207
185
|
class Conditions
|
208
186
|
|
209
187
|
def initialize(conditions = {}, fields)
|
210
|
-
@conditions, @fields = conditions.try(:with_indifferent_access) || {}, fields
|
188
|
+
@conditions, @fields, @operators = conditions.try(:with_indifferent_access) || {}, fields, {}
|
189
|
+
|
190
|
+
@conditions.each do |name, value|
|
191
|
+
_name, operator = name.to_s.split('.')
|
192
|
+
@operators[_name] = operator if operator
|
193
|
+
end
|
211
194
|
end
|
212
195
|
|
213
196
|
def prepare
|
214
|
-
|
215
|
-
|
197
|
+
# selects
|
216
198
|
_prepare(@fields.selects) do |field, value|
|
217
199
|
field.select_options.by_name(value).try(:_id)
|
218
200
|
end
|
219
201
|
|
220
|
-
|
202
|
+
# belongs_to
|
203
|
+
_prepare(@fields.belongs_to) { |field, value| value_to_id(value) }
|
204
|
+
|
205
|
+
# many_to_many
|
206
|
+
_prepare(@fields.many_to_many) { |field, value| values_to_ids(value) }
|
221
207
|
|
222
208
|
@conditions
|
223
209
|
end
|
@@ -226,13 +212,35 @@ module Locomotive
|
|
226
212
|
|
227
213
|
def _prepare(fields, &block)
|
228
214
|
fields.each do |field|
|
229
|
-
|
230
|
-
|
231
|
-
|
215
|
+
name = field.name.to_s
|
216
|
+
operator = @operators[name]
|
217
|
+
_name = operator ? "#{name}.#{operator}" : name
|
218
|
+
|
219
|
+
if value = @conditions[_name]
|
220
|
+
# delete old name
|
221
|
+
@conditions.delete(_name)
|
222
|
+
|
223
|
+
# build the new name with the prefix and the operator if there is one
|
224
|
+
_name = field.persisted_name + (operator ? ".#{operator}" : '')
|
225
|
+
|
226
|
+
# store the new name
|
227
|
+
@conditions[_name] = yield(field, value)
|
232
228
|
end
|
233
229
|
end
|
234
230
|
end
|
235
231
|
|
232
|
+
def value_to_id(value)
|
233
|
+
if value.respond_to?(:each) # array
|
234
|
+
values_to_ids(value)
|
235
|
+
else
|
236
|
+
value.respond_to?(:_id) ? value._id : value
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
def values_to_ids(value)
|
241
|
+
[*value].map { |_value| value_to_id(_value) }
|
242
|
+
end
|
243
|
+
|
236
244
|
end
|
237
245
|
|
238
246
|
end
|
@@ -30,7 +30,7 @@ module Locomotive
|
|
30
30
|
query do
|
31
31
|
where(k(:handle, :ne) => nil).
|
32
32
|
only(:_id, :title, :handle, :fullpath)
|
33
|
-
end.all
|
33
|
+
end.all.tap { mapper.reset_entity_map }
|
34
34
|
end
|
35
35
|
|
36
36
|
def by_handle(handle)
|
@@ -81,7 +81,7 @@ module Locomotive
|
|
81
81
|
end
|
82
82
|
|
83
83
|
def editable_element_for(page, block, slug)
|
84
|
-
return nil if page.nil?
|
84
|
+
return nil if page.nil? || page.editable_elements.nil?
|
85
85
|
page.editable_elements.first do
|
86
86
|
where(block: block, slug: slug)
|
87
87
|
end
|
@@ -7,15 +7,16 @@ module Locomotive
|
|
7
7
|
|
8
8
|
def parse(page)
|
9
9
|
_parse(page,
|
10
|
-
page:
|
11
|
-
parent_finder:
|
12
|
-
snippet_finder:
|
13
|
-
parser:
|
10
|
+
page: page,
|
11
|
+
parent_finder: parent_finder,
|
12
|
+
snippet_finder: snippet_finder,
|
13
|
+
parser: self,
|
14
|
+
default_editable_content: {})
|
14
15
|
end
|
15
16
|
|
16
17
|
def _parse(object, options = {})
|
17
18
|
# Note: the template must not be parsed here
|
18
|
-
::Liquid::Template.parse(object.liquid_source, options)
|
19
|
+
Locomotive::Steam::Liquid::Template.parse(object.liquid_source, options)
|
19
20
|
end
|
20
21
|
|
21
22
|
end
|
data/locomotivecms_steam.gemspec
CHANGED
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_dependency 'mongo', '~> 2.1.2'
|
22
22
|
spec.add_dependency 'origin', '~> 2.1.1'
|
23
23
|
|
24
|
+
spec.add_dependency 'nokogiri', '~> 1.6.6.4'
|
24
25
|
spec.add_dependency 'sanitize', '~> 4.0.0'
|
25
26
|
spec.add_dependency 'morphine', '~> 0.1.1'
|
26
27
|
spec.add_dependency 'httparty', '~> 0.13.6'
|
@@ -0,0 +1,43 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Locomotive::Steam::Liquid::Drops::Page do
|
4
|
+
|
5
|
+
describe '#editable_elements' do
|
6
|
+
|
7
|
+
let(:source) { <<-EOF
|
8
|
+
<h1>{{ page.editable_elements.content.header.title }}</h1>
|
9
|
+
{% block content %}
|
10
|
+
{% block header %}
|
11
|
+
{% editable_text title %}Hello world{% endeditable_text %}
|
12
|
+
{% endblock %}
|
13
|
+
{% endblock %}
|
14
|
+
EOF
|
15
|
+
}
|
16
|
+
|
17
|
+
let(:elements) { nil }
|
18
|
+
let(:page) { instance_double('Page', localized_attributes: [], fullpath: 'index', editable_elements: elements) }
|
19
|
+
let(:drop) { described_class.new(page) }
|
20
|
+
let(:services) { Locomotive::Steam::Services.build_instance }
|
21
|
+
let(:context) { ::Liquid::Context.new({ 'page' => drop }, {}, { page: page, services: services }, true) }
|
22
|
+
|
23
|
+
subject { render_template(source, context, { page: page, default_editable_content: {} }) }
|
24
|
+
|
25
|
+
it { is_expected.to match /<h1>Hello world<\/h1>/ }
|
26
|
+
|
27
|
+
context 'content updated by an user' do
|
28
|
+
|
29
|
+
let(:elements) { [instance_double('EditableText', block: 'content/header', slug: 'title', content: 'Bonjour le monde', :base_url= => nil, localized_attributes: [], format: 'raw')] }
|
30
|
+
|
31
|
+
before do
|
32
|
+
services.locale = :en
|
33
|
+
services.repositories.current_site = instance_double('Site', default_locale: :en)
|
34
|
+
allow(services.repositories.page).to receive(:editable_elements_of).and_return(elements)
|
35
|
+
end
|
36
|
+
|
37
|
+
it { is_expected.to match /<h1>Bonjour le monde<\/h1>/ }
|
38
|
+
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
data/spec/support/liquid.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
def render_template(source, context = nil, options = {})
|
2
2
|
context ||= ::Liquid::Context.new
|
3
3
|
context.exception_handler = ->(e) { true }
|
4
|
-
::Liquid::Template.parse(source, options).render(context)
|
4
|
+
Locomotive::Steam::Liquid::Template.parse(source, options).render(context)
|
5
5
|
end
|
6
6
|
|
7
7
|
def parse_template(source, options = nil)
|
@@ -23,4 +23,25 @@ describe Locomotive::Steam::Adapters::Filesystem::YAMLLoaders::ContentType do
|
|
23
23
|
|
24
24
|
end
|
25
25
|
|
26
|
+
describe '#build_select_options_from_hash' do
|
27
|
+
|
28
|
+
let(:options) { { en: ['General', 'Gigs', 'Bands'], fr: ['Général', 'Concerts', 'Groupes'] } }
|
29
|
+
|
30
|
+
subject { loader.send(:build_select_options_from_hash, options) }
|
31
|
+
|
32
|
+
it { is_expected.to eq [{ _id: 'General', name: { en: 'General', fr: 'Général' }, position: 0 }, { _id: 'Gigs', name: { en: 'Gigs', fr: 'Concerts' }, position: 1 }, { _id: 'Bands', name: { en: 'Bands', fr: 'Groupes' }, position: 2 }] }
|
33
|
+
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '#build_select_options_from_array' do
|
37
|
+
|
38
|
+
# let(:options) { { en: ['General', 'Gigs', 'Bands'], fr: ['Général', 'Concerts', 'Groupes'] } }
|
39
|
+
let(:options) { [{ en: 'General', fr: 'Général' }, { en: 'Gigs', fr: 'Concerts'}, { en: 'Bands', fr: 'Groupes' }] }
|
40
|
+
|
41
|
+
subject { loader.send(:build_select_options_from_array, options) }
|
42
|
+
|
43
|
+
it { is_expected.to eq [{ _id: 'General', name: { en: 'General', fr: 'Général' }, position: 0 }, { _id: 'Gigs', name: { en: 'Gigs', fr: 'Concerts' }, position: 1 }, { _id: 'Bands', name: { en: 'Bands', fr: 'Groupes' }, position: 2 }] }
|
44
|
+
|
45
|
+
end
|
46
|
+
|
26
47
|
end
|
@@ -90,7 +90,15 @@ describe Locomotive::Steam::Adapters::Memory::Condition do
|
|
90
90
|
describe '#array_contains?' do
|
91
91
|
let(:source) { [1, 2, 3, 4] }
|
92
92
|
let(:target) { [1, 2, 3] }
|
93
|
-
context '
|
93
|
+
context 'target contains the source' do
|
94
|
+
specify('should be true') do
|
95
|
+
expect(subject.send(:array_contains?, source, target)).to eq true
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
context 'target contains at least one element' do
|
100
|
+
let(:source) { [1] }
|
101
|
+
let(:target) { [1, 2, 3] }
|
94
102
|
specify('should be true') do
|
95
103
|
expect(subject.send(:array_contains?, source, target)).to eq true
|
96
104
|
end
|
@@ -44,6 +44,15 @@ describe Locomotive::Steam::Adapters::Memory::Order do
|
|
44
44
|
let(:entry) { instance_double('Entry', title: 'foo', date: Time.zone.now) }
|
45
45
|
it { expect(subject.map(&:class)).to eq([Locomotive::Steam::Adapters::Memory::Order::Asc, Locomotive::Steam::Adapters::Memory::Order::Desc]) }
|
46
46
|
|
47
|
+
context 'localized field' do
|
48
|
+
|
49
|
+
let(:now) { Time.zone.now }
|
50
|
+
let(:field) { instance_double('TitleI18nField', :[] => 'Hello world', translations: true) }
|
51
|
+
let(:entry) { instance_double('Entry', title: field, date: now) }
|
52
|
+
it { expect(subject.map(&:obj)).to eq(['Hello world', now]) }
|
53
|
+
|
54
|
+
end
|
55
|
+
|
47
56
|
end
|
48
57
|
|
49
58
|
describe 'sort' do
|
@@ -151,11 +151,11 @@ describe Locomotive::Steam::ContentEntry do
|
|
151
151
|
|
152
152
|
context 'a date time' do
|
153
153
|
let(:field_type) { :date_time }
|
154
|
-
let(:value) { '2007/06/29
|
155
|
-
let(:datetime) { DateTime.parse('2007/06/29
|
154
|
+
let(:value) { '2007/06/29 10:00:00' }
|
155
|
+
let(:datetime) { DateTime.parse('2007/06/29 10:00:00') }
|
156
156
|
it { is_expected.to eq datetime }
|
157
157
|
context 'localized' do
|
158
|
-
let(:value) { build_i18n_field(en: '2007/06/29
|
158
|
+
let(:value) { build_i18n_field(en: '2007/06/29 10:00:00', fr: datetime) }
|
159
159
|
it { expect(subject.translations).to eq('en' => datetime, 'fr' => datetime) }
|
160
160
|
end
|
161
161
|
end
|
@@ -70,7 +70,7 @@ describe Locomotive::Steam::Liquid::Drops::Page do
|
|
70
70
|
|
71
71
|
describe '#editable_elements' do
|
72
72
|
|
73
|
-
let(:elements) { [instance_double('EditableElement', block: 'top/left', slug: 'banner', content: 'Hello world')] }
|
73
|
+
let(:elements) { [instance_double('EditableElement', block: 'top/left', slug: 'banner', content: 'Hello world', localized_attributes: [])] }
|
74
74
|
|
75
75
|
before do
|
76
76
|
allow(services.repositories.page).to receive(:editable_elements_of).with(page).and_return(elements)
|
@@ -57,12 +57,31 @@ describe Locomotive::Steam::Liquid::Tags::Editable::Text do
|
|
57
57
|
it { is_expected.to include(block: nil) }
|
58
58
|
it { is_expected.to include(type: :editable_text) }
|
59
59
|
it { is_expected.to include(slug: 'title') }
|
60
|
+
it { is_expected.to include(label: nil) }
|
60
61
|
it { is_expected.to include(hint: 'Simple short text') }
|
61
62
|
it { is_expected.to include(format: 'html') }
|
62
63
|
it { is_expected.to include(rows: 10) }
|
63
64
|
it { is_expected.to include(line_break: true) }
|
64
65
|
it { is_expected.to include(content_from_default: 'Hello world') }
|
65
66
|
|
67
|
+
context 'with a defined slug' do
|
68
|
+
|
69
|
+
let(:source) { "{% editable_text 'First column', slug: 'column_1' %}{% endeditable_text %}" }
|
70
|
+
|
71
|
+
it { is_expected.to include(slug: 'column_1') }
|
72
|
+
it { is_expected.to include(label: 'First column') }
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'with a defined label' do
|
77
|
+
|
78
|
+
let(:source) { "{% editable_text 'first_column', label: 'Column #1' %}{% endeditable_text %}" }
|
79
|
+
|
80
|
+
it { is_expected.to include(slug: 'first_column') }
|
81
|
+
it { is_expected.to include(label: 'Column #1') }
|
82
|
+
|
83
|
+
end
|
84
|
+
|
66
85
|
end
|
67
86
|
|
68
87
|
end
|
@@ -75,7 +94,7 @@ describe Locomotive::Steam::Liquid::Tags::Editable::Text do
|
|
75
94
|
let(:element_editing) { true }
|
76
95
|
|
77
96
|
let(:child_page) { instance_double('Page', fullpath: 'child-page') }
|
78
|
-
let(:element) { instance_double('EditableText', _id: 42, id: 42,
|
97
|
+
let(:element) { instance_double('EditableText', _id: 42, id: 42, content: nil, inline_editing?: element_editing, inline_editing: element_editing, format: 'html') }
|
79
98
|
let(:services) { Locomotive::Steam::Services.build_instance(nil) }
|
80
99
|
let(:context) { ::Liquid::Context.new({}, {}, { page: child_page, services: services, live_editing: live_editing }) }
|
81
100
|
|
@@ -102,7 +121,7 @@ describe Locomotive::Steam::Liquid::Tags::Editable::Text do
|
|
102
121
|
let(:layout) { instance_double('Page', fullpath: 'layout') }
|
103
122
|
let(:source) { "{% editable_text title, hint: 'Simple short text', fixed: true %}Hello world{% endeditable_text %}" }
|
104
123
|
let(:options) { { page: layout } }
|
105
|
-
let(:element) { instance_double('EditableText', _id: 42, id: 42,
|
124
|
+
let(:element) { instance_double('EditableText', _id: 42, id: 42, content: nil, inline_editing?: element_editing, inline_editing: element_editing, format: 'html', fixed: true) }
|
106
125
|
|
107
126
|
it 'fetches the related page in order to get the element' do
|
108
127
|
expect(services.page_finder).to receive(:find).with('layout').and_return(layout)
|
@@ -113,7 +132,7 @@ describe Locomotive::Steam::Liquid::Tags::Editable::Text do
|
|
113
132
|
|
114
133
|
context 'modified content' do
|
115
134
|
|
116
|
-
let(:element) { instance_double('EditableText', content: 'Hello world!',
|
135
|
+
let(:element) { instance_double('EditableText', content: 'Hello world!', format: 'html') }
|
117
136
|
it { is_expected.to eq 'Hello world!' }
|
118
137
|
|
119
138
|
end
|
@@ -129,7 +148,7 @@ describe Locomotive::Steam::Liquid::Tags::Editable::Text do
|
|
129
148
|
|
130
149
|
context 'markdown format' do
|
131
150
|
|
132
|
-
let(:element) { instance_double('EditableText', content: "#Hello world!\nLorem ipsum",
|
151
|
+
let(:element) { instance_double('EditableText', content: "#Hello world!\nLorem ipsum", format: 'markdown') }
|
133
152
|
it { is_expected.to eq "<h1>Hello world!</h1>\n<p>Lorem ipsum</p>\n" }
|
134
153
|
|
135
154
|
end
|
@@ -27,12 +27,30 @@ describe Locomotive::Steam::Liquid::Tags::Extends do
|
|
27
27
|
|
28
28
|
let!(:template) { parse_template(source, options) }
|
29
29
|
|
30
|
-
let(:parent) { instance_double('Index', localized_attributes: { source: true, template: true }, source: { en: 'Hello world!' }, template: { en: nil }) }
|
30
|
+
let(:parent) { instance_double('Index', handle: nil, slug: nil, localized_attributes: { source: true, template: true }, source: { en: 'Hello world!' }, template: { en: nil }) }
|
31
31
|
|
32
32
|
it { expect(listener.event_names.first).to eq 'steam.parse.extends' }
|
33
33
|
it { expect(template.render).to eq 'Hello world!' }
|
34
34
|
it { expect(options[:page]).to eq page }
|
35
35
|
|
36
|
+
describe 'set the layout name' do
|
37
|
+
|
38
|
+
let(:source) { '{% extends parent %}{% block message %}My layout: {{ layout_name }}{% endblock %}' }
|
39
|
+
|
40
|
+
let(:parent) { instance_double('Index', handle: nil, slug: 'index', localized_attributes: { source: true, template: true }, source: { en: 'Hello world! {% block message %}{% endblock %}' }, template: { en: nil }) }
|
41
|
+
|
42
|
+
it { expect(template.render).to eq 'Hello world! My layout: index' }
|
43
|
+
|
44
|
+
context 'the handle of the parent page exists' do
|
45
|
+
|
46
|
+
let(:parent) { instance_double('Index', handle: 'home', slug: 'index', localized_attributes: { source: true, template: true }, source: { en: 'Hello world! {% block message %}{% endblock %}' }, template: { en: nil }) }
|
47
|
+
|
48
|
+
it { expect(template.render).to eq 'Hello world! My layout: home' }
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
end
|
53
|
+
|
36
54
|
end
|
37
55
|
|
38
56
|
end
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe Locomotive::Steam::Liquid::Tags::InheritedBlock do
|
4
4
|
|
5
5
|
let(:parent_source) { 'My product: {% block product %}Random{% endblock %}' }
|
6
|
-
let(:parent) { instance_double('Index', liquid_source: parent_source, template: nil, :template= => nil) }
|
6
|
+
let(:parent) { instance_double('Index', liquid_source: parent_source, template: nil, :template= => nil, slug: nil, handle: nil) }
|
7
7
|
let(:source) { '{% extends parent %}{% block product %}Skis{% endblock %}' }
|
8
8
|
let(:page) { instance_double('Page') }
|
9
9
|
|
@@ -25,6 +25,27 @@ describe Locomotive::Steam::Liquid::Tags::WithScope do
|
|
25
25
|
|
26
26
|
end
|
27
27
|
|
28
|
+
describe 'decode content entry' do
|
29
|
+
|
30
|
+
let(:entry) {
|
31
|
+
instance_double('ContentEntry', _id: 1, _source: 'entity').tap do |_entry|
|
32
|
+
allow(_entry).to receive(:to_liquid).and_return(_entry)
|
33
|
+
end }
|
34
|
+
let(:assigns) { { 'my_project' => entry } }
|
35
|
+
let(:source) { "{% with_scope project: my_project %}{% assign conditions = with_scope %}{% endwith_scope %}" }
|
36
|
+
|
37
|
+
it { expect(conditions['project']).to eq 'entity' }
|
38
|
+
|
39
|
+
context 'an array of content entries' do
|
40
|
+
|
41
|
+
let(:source) { "{% with_scope project: [my_project, my_project, my_project] %}{% assign conditions = with_scope %}{% endwith_scope %}" }
|
42
|
+
|
43
|
+
it { expect(conditions['project']).to eq ['entity', 'entity', 'entity'] }
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
28
49
|
describe 'decode context variable' do
|
29
50
|
|
30
51
|
let(:assigns) { { 'params' => { 'type' => 'posts' } } }
|
@@ -4,7 +4,7 @@ require_relative '../../../lib/locomotive/steam/adapters/filesystem.rb'
|
|
4
4
|
|
5
5
|
describe Locomotive::Steam::ContentEntryRepository do
|
6
6
|
|
7
|
-
let(:_fields) { instance_double('Fields', selects: [], belongs_to: []) }
|
7
|
+
let(:_fields) { instance_double('Fields', selects: [], belongs_to: [], many_to_many: []) }
|
8
8
|
let(:type) { build_content_type('Articles', label_field_name: :title, localized_names: [:title], fields: _fields, fields_by_name: { title: instance_double('Field', name: :title, type: :string) }) }
|
9
9
|
let(:entries) { [{ content_type_id: 1, _position: 0, _label: 'Update #1', title: { fr: 'Mise a jour #1' }, text: { en: 'added some free stuff', fr: 'phrase FR' }, date: '2009/05/12', category: 'General' }] }
|
10
10
|
let(:locale) { :en }
|
@@ -248,7 +248,7 @@ describe Locomotive::Steam::ContentEntryRepository do
|
|
248
248
|
let(:other_type) { build_content_type('Authors', _id: 2, label_field_name: :name, fields: _fields, fields_by_name: { name: instance_double('Field', name: :name, type: :string) }) }
|
249
249
|
let(:other_entries) { [{ content_type_id: 2, _id: 'john-doe', name: 'John Doe' }] }
|
250
250
|
|
251
|
-
let(:type_repository) { instance_double('ArticleBelongsToRepository', selects: [], belongs_to: []) }
|
251
|
+
let(:type_repository) { instance_double('ArticleBelongsToRepository', selects: [], belongs_to: [], many_to_many: []) }
|
252
252
|
|
253
253
|
before do
|
254
254
|
allow(type).to receive(:fields).and_return(type_repository)
|
@@ -281,7 +281,7 @@ describe Locomotive::Steam::ContentEntryRepository do
|
|
281
281
|
]
|
282
282
|
}
|
283
283
|
|
284
|
-
let(:type_repository) { instance_double('AuthorRepository', selects: [], belongs_to: []) }
|
284
|
+
let(:type_repository) { instance_double('AuthorRepository', selects: [], belongs_to: [], many_to_many: []) }
|
285
285
|
|
286
286
|
before do
|
287
287
|
allow(type).to receive(:fields).and_return(type_repository)
|
@@ -314,7 +314,7 @@ describe Locomotive::Steam::ContentEntryRepository do
|
|
314
314
|
]
|
315
315
|
}
|
316
316
|
|
317
|
-
let(:type_repository) { instance_double('AuthorRepository', selects: [], belongs_to: []) }
|
317
|
+
let(:type_repository) { instance_double('AuthorRepository', selects: [], belongs_to: [], many_to_many: []) }
|
318
318
|
|
319
319
|
before do
|
320
320
|
allow(type).to receive(:fields).and_return(type_repository)
|
@@ -333,6 +333,76 @@ describe Locomotive::Steam::ContentEntryRepository do
|
|
333
333
|
|
334
334
|
end
|
335
335
|
|
336
|
+
describe '#conditions_without_order_by' do
|
337
|
+
|
338
|
+
let(:conditions) { {} }
|
339
|
+
|
340
|
+
subject { repository.with(type).send(:conditions_without_order_by, conditions) }
|
341
|
+
|
342
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1 }, nil]) }
|
343
|
+
|
344
|
+
context 'select fields' do
|
345
|
+
|
346
|
+
let(:value) { 'CMS' }
|
347
|
+
let(:option) { instance_double('Option', _id: 42)}
|
348
|
+
let(:options) { instance_double('OptionRepository', by_name: option) }
|
349
|
+
let(:field) { instance_double('SelectField', name: 'category', persisted_name: 'category_id', select_options: options) }
|
350
|
+
let(:_fields) { instance_double('Fields', selects: [field], belongs_to: [], many_to_many: []) }
|
351
|
+
let(:conditions) { { 'category' => value } }
|
352
|
+
|
353
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1, 'category_id' => 42 }, nil]) }
|
354
|
+
|
355
|
+
end
|
356
|
+
|
357
|
+
context 'belongs_to fields' do
|
358
|
+
|
359
|
+
let(:value) { 42 }
|
360
|
+
let(:field) { instance_double('BelongsToField', name: 'person', persisted_name: 'person_id') }
|
361
|
+
let(:_fields) { instance_double('Fields', selects: [], belongs_to: [field], many_to_many: []) }
|
362
|
+
let(:conditions) { { 'person' => value } }
|
363
|
+
|
364
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1, 'person_id' => 42 }, nil]) }
|
365
|
+
|
366
|
+
context 'the target value is a content entry' do
|
367
|
+
|
368
|
+
let(:value) { instance_double('TargetContentEntry', _id: 1) }
|
369
|
+
|
370
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1, 'person_id' => 1 }, nil]) }
|
371
|
+
|
372
|
+
end
|
373
|
+
|
374
|
+
context 'the target value is an arry of content entry' do
|
375
|
+
|
376
|
+
let(:value) { [instance_double('TargetContentEntry', _id: 1), instance_double('TargetContentEntry', _id: 2)] }
|
377
|
+
let(:conditions) { { 'person.in' => value } }
|
378
|
+
|
379
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1, 'person_id.in' => [1, 2] }, nil]) }
|
380
|
+
|
381
|
+
end
|
382
|
+
|
383
|
+
end
|
384
|
+
|
385
|
+
context 'many_to_many fields' do
|
386
|
+
|
387
|
+
let(:value) { 42 }
|
388
|
+
let(:field) { instance_double('ManyToManyField', name: 'tags', persisted_name: 'tag_ids') }
|
389
|
+
let(:_fields) { instance_double('Fields', selects: [], belongs_to: [], many_to_many: [field]) }
|
390
|
+
let(:conditions) { { 'tags.in' => value } }
|
391
|
+
|
392
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1, 'tag_ids.in' => [42] }, nil]) }
|
393
|
+
|
394
|
+
context 'the target value is a content entry' do
|
395
|
+
|
396
|
+
let(:value) { [instance_double('TargetContentEntry', _id: 1), 42] }
|
397
|
+
|
398
|
+
it { is_expected.to eq([{ _visible: true, content_type_id: 1, 'tag_ids.in' => [1, 42] }, nil]) }
|
399
|
+
|
400
|
+
end
|
401
|
+
|
402
|
+
end
|
403
|
+
|
404
|
+
end
|
405
|
+
|
336
406
|
def build_content_type(name, attributes = {})
|
337
407
|
instance_double(name,
|
338
408
|
{
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: locomotivecms_steam
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0.
|
4
|
+
version: 1.0.0.rc8
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Didier Lafforgue
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date: 2015-
|
14
|
+
date: 2015-12-05 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: bundler
|
@@ -69,6 +69,20 @@ dependencies:
|
|
69
69
|
- - "~>"
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: 2.1.1
|
72
|
+
- !ruby/object:Gem::Dependency
|
73
|
+
name: nokogiri
|
74
|
+
requirement: !ruby/object:Gem::Requirement
|
75
|
+
requirements:
|
76
|
+
- - "~>"
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 1.6.6.4
|
79
|
+
type: :runtime
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: 1.6.6.4
|
72
86
|
- !ruby/object:Gem::Dependency
|
73
87
|
name: sanitize
|
74
88
|
requirement: !ruby/object:Gem::Requirement
|
@@ -489,6 +503,7 @@ files:
|
|
489
503
|
- lib/locomotive/steam/liquid/tags/session_assign.rb
|
490
504
|
- lib/locomotive/steam/liquid/tags/snippet.rb
|
491
505
|
- lib/locomotive/steam/liquid/tags/with_scope.rb
|
506
|
+
- lib/locomotive/steam/liquid/template.rb
|
492
507
|
- lib/locomotive/steam/middlewares.rb
|
493
508
|
- lib/locomotive/steam/middlewares/default_env.rb
|
494
509
|
- lib/locomotive/steam/middlewares/dynamic_assets.rb
|
@@ -649,6 +664,7 @@ files:
|
|
649
664
|
- spec/fixtures/mongodb/locomotive_translations.metadata.json
|
650
665
|
- spec/fixtures/mongodb/system.indexes.bson
|
651
666
|
- spec/integration/integration_helper.rb
|
667
|
+
- spec/integration/liquid/drops/page_spec.rb
|
652
668
|
- spec/integration/liquid/tags/paginate_spec.rb
|
653
669
|
- spec/integration/repositories/content_entry_repository_spec.rb
|
654
670
|
- spec/integration/repositories/content_type_repository_spec.rb
|
@@ -890,6 +906,7 @@ test_files:
|
|
890
906
|
- spec/fixtures/mongodb/locomotive_translations.metadata.json
|
891
907
|
- spec/fixtures/mongodb/system.indexes.bson
|
892
908
|
- spec/integration/integration_helper.rb
|
909
|
+
- spec/integration/liquid/drops/page_spec.rb
|
893
910
|
- spec/integration/liquid/tags/paginate_spec.rb
|
894
911
|
- spec/integration/repositories/content_entry_repository_spec.rb
|
895
912
|
- spec/integration/repositories/content_type_repository_spec.rb
|