editmode 1.2.1 → 1.2.6
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.
- checksums.yaml +4 -4
- data/README.md +8 -0
- data/lib/editmode/action_view_extensions/editmode_helper.rb +22 -78
- data/lib/editmode/chunk_value.rb +88 -30
- data/lib/editmode/helper.rb +26 -9
- data/lib/editmode/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 84c4ada25fc650fcb7f2a9b9c8322562bda944bd1180815e60bf3f3ef7534d94
|
4
|
+
data.tar.gz: 246e38a66ff7fb77ca953ef0e222720defdc72447eac982bdf5e39c7c0b34a0f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c891c169c1759113a86a6cf8daa6f7910b676e5296b036784cf37a2dec35f6d82b3237d8284027ecb3bb6126c9e168de5dcbceedc8f6829161bd6a7b844cb25
|
7
|
+
data.tar.gz: a674897c9c9a1c5ef04f95fb378982343557dd14f03e4b5e55a6093cbf470b56ef663aa7c3bed30bb7e475c53b5a4ee3b1164143bc7e1e83e545cb8ef74feeac
|
data/README.md
CHANGED
@@ -50,6 +50,12 @@ Editmode provides helper methods for use in your rails views and controllers.
|
|
50
50
|
<%= E('cnk_x4ts...', class: "a-css-class") %> # Render a chunk with inline css class
|
51
51
|
```
|
52
52
|
|
53
|
+
### Working with multiple projects in the same codebase
|
54
|
+
If you want to include content from a different project to the one you've specified in the initializer, you can pass the project id in to the view helper.
|
55
|
+
```erb
|
56
|
+
<%= E("cnk_16e04a02d577afb610ce", project_id: "prj_02d577afb617hdb") %>
|
57
|
+
```
|
58
|
+
|
53
59
|
### Content can also be accessed in Controllers
|
54
60
|
```ruby
|
55
61
|
@page_title = e("cnk_x4ts............") # Using a chunk identifier
|
@@ -78,6 +84,8 @@ e("cnk_16e04a02d577afb610ce", "Email Content", variables: variable_values)
|
|
78
84
|
# Response: "Hi Dexter Morgan"
|
79
85
|
```
|
80
86
|
|
87
|
+
|
88
|
+
|
81
89
|
### Use collections for repeatable content
|
82
90
|
```erb
|
83
91
|
<%= c('col_j8fbs...', class: "profiles-container", item_class: "profile-item") do %>
|
@@ -56,14 +56,14 @@ module Editmode
|
|
56
56
|
chunks.each do |chunk|
|
57
57
|
@custom_field_chunk = chunk
|
58
58
|
concat(content_tag(:div, class: "chunks-collection-item--wrapper #{item_class}") do
|
59
|
-
yield
|
59
|
+
yield(@custom_field_chunk)
|
60
60
|
end)
|
61
61
|
end
|
62
62
|
|
63
63
|
# Placeholder element for new collection item
|
64
64
|
@custom_field_chunk = chunks.first.merge!({placeholder: true})
|
65
65
|
concat(content_tag(:div, class: "chunks-hide chunks-col-placeholder-wrapper") do
|
66
|
-
yield
|
66
|
+
yield(@custom_field_chunk)
|
67
67
|
end)
|
68
68
|
end
|
69
69
|
else
|
@@ -80,9 +80,8 @@ module Editmode
|
|
80
80
|
def chunk_field_value(parent_chunk_object, custom_field_identifier, options = {})
|
81
81
|
begin
|
82
82
|
chunk_identifier = parent_chunk_object["identifier"]
|
83
|
-
|
84
|
-
|
85
|
-
end
|
83
|
+
chunk_value = Editmode::ChunkValue.new(parent_chunk_object["identifier"], options.merge({response: parent_chunk_object}))
|
84
|
+
custom_field_item = chunk_value.field_chunk(custom_field_identifier)
|
86
85
|
|
87
86
|
options[:field] = custom_field_identifier
|
88
87
|
|
@@ -94,7 +93,7 @@ module Editmode
|
|
94
93
|
if custom_field_item.present?
|
95
94
|
render_chunk_content(
|
96
95
|
custom_field_item["identifier"],
|
97
|
-
|
96
|
+
chunk_value.field(custom_field_identifier),
|
98
97
|
custom_field_item["chunk_type"],
|
99
98
|
{ parent_identifier: chunk_identifier, custom_field_identifier: custom_field_identifier}.merge(options)
|
100
99
|
)
|
@@ -106,12 +105,7 @@ module Editmode
|
|
106
105
|
end
|
107
106
|
|
108
107
|
def render_chunk_content(chunk_identifier, chunk_content, chunk_type,options = {})
|
109
|
-
|
110
108
|
begin
|
111
|
-
# Always sanitize the content!!
|
112
|
-
chunk_content = ActionController::Base.helpers.sanitize(chunk_content) unless chunk_type == 'rich_text'
|
113
|
-
chunk_content = variable_parse!(chunk_content, options[:variable_fallbacks], options[:variable_values])
|
114
|
-
|
115
109
|
css_class = options[:class]
|
116
110
|
cache_id = options[:cache_identifier]
|
117
111
|
|
@@ -126,6 +120,8 @@ module Editmode
|
|
126
120
|
chunk_data.merge!({parent_identifier: options[:parent_identifier]}) if options[:parent_identifier].present?
|
127
121
|
chunk_data.merge!({custom_field_identifier: options[:custom_field_identifier]}) if options[:custom_field_identifier].present?
|
128
122
|
chunk_data.merge!({chunk_cache_id: cache_id}) if cache_id.present?
|
123
|
+
chunk_data.merge!({chunk_collection_identifier: options[:collection_id]}) if options[:collection_id].present?
|
124
|
+
chunk_data.merge!({chunk_content_key: options[:content_key]}) if options[:content_key].present?
|
129
125
|
|
130
126
|
case display_type
|
131
127
|
when "span"
|
@@ -150,61 +146,31 @@ module Editmode
|
|
150
146
|
end
|
151
147
|
|
152
148
|
def chunk_display(label, identifier, options = {}, &block)
|
153
|
-
branch_id = params[:em_branch_id]
|
149
|
+
options[:branch_id] = params[:em_branch_id] if params[:em_branch_id].present?
|
154
150
|
# This method should never show an error.
|
155
151
|
# If anything goes wrong fetching content
|
156
152
|
# We should just show blank content, not
|
157
153
|
# prevent the page from loading.
|
158
154
|
begin
|
159
|
-
branch_params = branch_id.present? ? "branch_id=#{branch_id}" : ""
|
160
155
|
field = options[:field].presence || ""
|
161
|
-
cache_identifier = "chunk_#{identifier}#{branch_id}#{field}"
|
162
|
-
url = "#{api_root_url}/chunks/#{identifier}?project_id=#{Editmode.project_id}&#{branch_params}"
|
163
|
-
cached_content_present = Rails.cache.exist?(cache_identifier)
|
164
|
-
parent_identifier = identifier if field.present?
|
165
|
-
if !cached_content_present
|
166
|
-
response = HTTParty.get(url)
|
167
|
-
response_received = true if response.code == 200
|
168
|
-
end
|
169
156
|
|
170
|
-
|
171
|
-
|
157
|
+
chunk_value = Editmode::ChunkValue.new(identifier, options)
|
158
|
+
|
159
|
+
if field.present? && chunk_value.chunk_type == 'collection_item'
|
160
|
+
chunk_content = chunk_value.field(field)
|
161
|
+
identifier = chunk_value.field_chunk(field)["identifier"]
|
162
|
+
chunk_type = chunk_value.field_chunk(field)["chunk_type"]
|
163
|
+
options[:collection_id] = chunk_value.collection_id
|
172
164
|
else
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
content = field_content["content"]
|
177
|
-
type = field_content["chunk_type"]
|
178
|
-
identifier = Rails.cache.fetch("#{cache_identifier}_field_identifier") do
|
179
|
-
field_content["identifier"]
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
variable_fallbacks = Rails.cache.fetch("#{cache_identifier}_variables") do
|
185
|
-
response['variable_fallbacks'].presence || {}
|
186
|
-
end
|
187
|
-
|
188
|
-
chunk_content = Rails.cache.fetch(cache_identifier) do
|
189
|
-
content.presence || response["content"]
|
190
|
-
end
|
191
|
-
|
192
|
-
chunk_type = Rails.cache.fetch("#{cache_identifier}_type") do
|
193
|
-
type.presence || response['chunk_type']
|
194
|
-
end
|
195
|
-
|
196
|
-
identifier = Rails.cache.fetch("#{cache_identifier}_field_identifier") do
|
197
|
-
identifier
|
198
|
-
end
|
199
|
-
|
200
|
-
options[:variable_fallbacks] = variable_fallbacks
|
201
|
-
options[:variable_values] = options[:variables].presence || {}
|
202
|
-
|
203
|
-
options[:cache_identifier] = parent_identifier.presence || identifier
|
204
|
-
|
205
|
-
render_chunk_content(identifier,chunk_content,chunk_type, options)
|
165
|
+
chunk_content = chunk_value.content
|
166
|
+
chunk_type = chunk_value.chunk_type
|
167
|
+
identifier = chunk_value.response["identifier"] unless identifier.include? "cnk_"
|
206
168
|
end
|
207
169
|
|
170
|
+
options[:cache_identifier] = chunk_value.identifier
|
171
|
+
options[:content_key] = chunk_value.response.try(:[], "content_key")
|
172
|
+
render_chunk_content(identifier, chunk_content, chunk_type, options)
|
173
|
+
|
208
174
|
rescue => error
|
209
175
|
# Show fallback content by default
|
210
176
|
return content_tag("em-span", &block) if block_given?
|
@@ -231,28 +197,6 @@ module Editmode
|
|
231
197
|
end
|
232
198
|
alias_method :E, :render_chunk
|
233
199
|
|
234
|
-
|
235
|
-
def variable_parse!(content, variables = {}, values = {}, raw = false)
|
236
|
-
tokens = content.scan(/\{{(.*?)\}}/)
|
237
|
-
if tokens.any?
|
238
|
-
tokens.flatten!
|
239
|
-
tokens.each do |token|
|
240
|
-
token_value = values[token.to_sym] || variables[token] || ""
|
241
|
-
sanitized_value = ActionController::Base.helpers.sanitize(token_value)
|
242
|
-
|
243
|
-
unless raw
|
244
|
-
sanitized_value = content_tag("em-var", :data => {chunk_variable: token, chunk_variable_value: sanitized_value}) do
|
245
|
-
sanitized_value
|
246
|
-
end
|
247
|
-
end
|
248
|
-
|
249
|
-
content.gsub!("{{#{token}}}", sanitized_value)
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
content
|
254
|
-
end
|
255
|
-
|
256
200
|
def no_response_received(id = "")
|
257
201
|
"Sorry, we can't find a chunk using this identifier: \"#{id}\". This can happen if you've deleted a chunk on editmode.com or if your local cache is out of date. If it persists, try running Rails.cache clear."
|
258
202
|
end
|
data/lib/editmode/chunk_value.rb
CHANGED
@@ -1,29 +1,42 @@
|
|
1
1
|
module Editmode
|
2
2
|
class ChunkValue
|
3
|
-
include
|
3
|
+
include ActionView::Helpers::TagHelper
|
4
|
+
include ActionView::Context
|
5
|
+
|
6
|
+
attr_accessor :identifier, :variable_values, :branch_id,
|
7
|
+
:variable_fallbacks, :chunk_type, :project_id,
|
8
|
+
:url, :collection_id, :cache_identifier,
|
9
|
+
:response
|
4
10
|
|
5
|
-
attr_accessor :identifier, :variable_values, :branch_id,
|
6
|
-
:variable_fallbacks, :chunk_type, :project_id,
|
7
|
-
:response
|
8
|
-
|
9
11
|
attr_writer :content
|
10
12
|
|
11
|
-
def initialize(identifier, **options)
|
13
|
+
def initialize(identifier, project_id: Editmode.project_id, **options)
|
12
14
|
@identifier = identifier
|
13
15
|
@branch_id = options[:branch_id].presence
|
16
|
+
@project_id = project_id
|
14
17
|
@variable_values = options[:variables].presence || {}
|
15
|
-
|
18
|
+
@raw = options[:raw].present?
|
19
|
+
@skip_sanitize = options[:dangerously_skip_sanitization]
|
20
|
+
|
21
|
+
@url = "#{api_root_url}/chunks/#{identifier}"
|
22
|
+
@cache_identifier = set_cache_identifier(identifier)
|
23
|
+
|
24
|
+
if options[:response].present?
|
25
|
+
@response = options[:response]
|
26
|
+
set_response_attributes!
|
27
|
+
else
|
28
|
+
get_content
|
29
|
+
end
|
16
30
|
end
|
17
31
|
|
18
|
-
def field(field = nil)
|
32
|
+
def field(field = nil)
|
19
33
|
# Field ID can be a slug or field_name
|
20
34
|
if chunk_type == 'collection_item'
|
21
35
|
if field.present?
|
22
|
-
field
|
23
|
-
|
24
|
-
|
25
|
-
result =
|
26
|
-
result = variable_parse!(result, variable_fallbacks, variable_values, true)
|
36
|
+
field_chunk = field_chunk(field)
|
37
|
+
if field_chunk.present?
|
38
|
+
result = field_chunk['content']
|
39
|
+
result = variable_parse!(result, variable_fallbacks, variable_values, @raw, @skip_sanitize)
|
27
40
|
else
|
28
41
|
raise no_response_received(field)
|
29
42
|
end
|
@@ -37,15 +50,29 @@ module Editmode
|
|
37
50
|
result.try(:html_safe)
|
38
51
|
end
|
39
52
|
|
53
|
+
def field_chunk(field)
|
54
|
+
field.downcase!
|
55
|
+
@content.detect {|f| f["custom_field_identifier"].downcase == field || f["custom_field_name"].downcase == field }
|
56
|
+
end
|
57
|
+
|
40
58
|
def content
|
41
|
-
raise "undefined method 'content
|
42
|
-
|
43
|
-
result = variable_parse!(@content, variable_fallbacks, variable_values,
|
59
|
+
raise "undefined method 'content' for chunk_type: collection_item \nDid you mean? field" if chunk_type == 'collection_item'
|
60
|
+
|
61
|
+
result = variable_parse!(@content, variable_fallbacks, variable_values, @raw, @skip_sanitize)
|
44
62
|
result.try(:html_safe)
|
45
63
|
end
|
46
64
|
|
47
65
|
private
|
48
66
|
|
67
|
+
# Todo: Transfer to helper utils
|
68
|
+
def api_root_url
|
69
|
+
ENV["EDITMODE_OVERRIDE_API_URL"] || "https://api.editmode.com"
|
70
|
+
end
|
71
|
+
|
72
|
+
def set_cache_identifier(id)
|
73
|
+
"chunk_#{project_id}#{branch_id}#{id}"
|
74
|
+
end
|
75
|
+
|
49
76
|
def json?(json)
|
50
77
|
JSON.parse(json)
|
51
78
|
return true
|
@@ -53,19 +80,46 @@ module Editmode
|
|
53
80
|
return false
|
54
81
|
end
|
55
82
|
|
56
|
-
def
|
57
|
-
|
58
|
-
|
83
|
+
def variable_parse!(content, variables = {}, values = {}, raw = true, skip_sanitize=false)
|
84
|
+
content = ActionController::Base.helpers.sanitize(content) unless skip_sanitize
|
85
|
+
tokens = content.scan(/\{{(.*?)\}}/)
|
86
|
+
if tokens.any?
|
87
|
+
tokens.flatten!
|
88
|
+
tokens.each do |token|
|
89
|
+
token_value = values[token.to_sym] || variables[token] || ""
|
90
|
+
sanitized_value = ActionController::Base.helpers.sanitize(token_value)
|
59
91
|
|
60
|
-
|
61
|
-
|
92
|
+
unless raw
|
93
|
+
sanitized_value = content_tag("em-var", :data => {chunk_variable: token, chunk_variable_value: sanitized_value}) do
|
94
|
+
sanitized_value
|
95
|
+
end
|
96
|
+
end
|
62
97
|
|
63
|
-
|
64
|
-
|
98
|
+
content.gsub!("{{#{token}}}", sanitized_value)
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
content
|
103
|
+
end
|
104
|
+
|
105
|
+
def cached?
|
106
|
+
Rails.cache.exist?(cache_identifier)
|
107
|
+
end
|
108
|
+
|
109
|
+
def query_params
|
110
|
+
the_params = { 'project_id' => project_id }
|
111
|
+
the_params['branch_id'] = branch_id if branch_id.present?
|
112
|
+
|
113
|
+
the_params
|
114
|
+
end
|
115
|
+
|
116
|
+
def get_content
|
117
|
+
if !cached?
|
118
|
+
http_response = HTTParty.get(url, query: query_params)
|
65
119
|
response_received = true if http_response.code == 200
|
66
120
|
end
|
67
121
|
|
68
|
-
if !
|
122
|
+
if !cached? && !response_received
|
69
123
|
raise no_response_received(identifier)
|
70
124
|
else
|
71
125
|
cached_response = Rails.cache.fetch(cache_identifier) do
|
@@ -73,13 +127,17 @@ module Editmode
|
|
73
127
|
end
|
74
128
|
|
75
129
|
@response = json?(cached_response) ? JSON.parse(cached_response) : cached_response
|
130
|
+
set_response_attributes!
|
131
|
+
end
|
132
|
+
end
|
76
133
|
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
134
|
+
def set_response_attributes!
|
135
|
+
@content = response['content']
|
136
|
+
@chunk_type = response['chunk_type']
|
137
|
+
@variable_fallbacks = response['variable_fallbacks'].presence || {}
|
138
|
+
@collection_id = response["collection"]["identifier"] if chunk_type == 'collection_item'
|
139
|
+
@branch_id = response['branch_id']
|
82
140
|
end
|
83
141
|
|
84
142
|
end
|
85
|
-
end
|
143
|
+
end
|
data/lib/editmode/helper.rb
CHANGED
@@ -4,20 +4,37 @@ module Editmode
|
|
4
4
|
def e(identifier, *args)
|
5
5
|
field, options = parse_arguments(args)
|
6
6
|
begin
|
7
|
-
chunk = Editmode::ChunkValue.new(identifier, options)
|
8
|
-
|
9
|
-
if chunk.chunk_type == 'collection_item'
|
10
|
-
chunk.field(field)
|
11
|
-
else
|
12
|
-
chunk.content
|
13
|
-
end
|
7
|
+
chunk = Editmode::ChunkValue.new(identifier, options.merge({raw: true}))
|
8
|
+
render_noneditable_chunk(chunk, field, options)
|
14
9
|
rescue => er
|
15
10
|
puts er
|
16
11
|
end
|
17
12
|
end
|
18
13
|
|
14
|
+
def render_noneditable_chunk(chunk, field=nil, options=nil)
|
15
|
+
return render_collection_item(chunk, field, options) if chunk.chunk_type == 'collection_item'
|
16
|
+
|
17
|
+
render_content(chunk, options)
|
18
|
+
end
|
19
|
+
|
20
|
+
def render_collection_item(chunk, field=nil, options=nil)
|
21
|
+
return render_image(chunk.field(field), options[:class]) if chunk.field_chunk(field)['chunk_type'] == 'image'
|
22
|
+
|
23
|
+
chunk.field(field)
|
24
|
+
end
|
25
|
+
|
26
|
+
def render_content(chunk, options=nil)
|
27
|
+
return render_image(chunk.content, options[:class]) if chunk.chunk_type == 'image'
|
28
|
+
|
29
|
+
chunk.content
|
30
|
+
end
|
31
|
+
|
32
|
+
def render_image(content, css_class=nil)
|
33
|
+
image_tag(content, class: css_class)
|
34
|
+
end
|
35
|
+
|
19
36
|
def render_custom_field_raw(label, options={})
|
20
|
-
e(@custom_field_chunk["identifier"], label, options)
|
37
|
+
e(@custom_field_chunk["identifier"], label, options.merge({response: @custom_field_chunk}))
|
21
38
|
end
|
22
39
|
alias_method :f, :render_custom_field_raw
|
23
40
|
|
@@ -33,4 +50,4 @@ module Editmode
|
|
33
50
|
return field, options
|
34
51
|
end
|
35
52
|
end
|
36
|
-
end
|
53
|
+
end
|
data/lib/editmode/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: editmode
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tony Ennis
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|