wcc-contentful 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +5 -1
- data/lib/wcc/contentful/engine.rb +27 -25
- data/lib/wcc/contentful/rich_text_renderer.rb +52 -4
- data/lib/wcc/contentful/test/double.rb +2 -2
- data/lib/wcc/contentful/test/factory.rb +2 -2
- data/lib/wcc/contentful/version.rb +1 -1
- metadata +14 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d67d393afd50ea2c1ab321eea762d18111df439d4058f4cdf2281d43418b9b86
|
4
|
+
data.tar.gz: 64b7149e4a25410576287ea71692bccb23878e7c9b12b3b013cdaf08f4d1c79c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8458a30bd45a736ce11777e43c1376c887515f2870db10511cffd4361675506fa723fc400e280b68f19c0fb74d340c452c3a055ecf06032424337c2f14425dd7
|
7
|
+
data.tar.gz: 27b2af13bfad415a2f385fb1d641178ea5496e1e9080ae21071807cc3a3c662422675f6943422b9e7824b87f0eca1a8e4c4c64743a898e732637ecebf23345ab
|
data/README.md
CHANGED
@@ -74,10 +74,14 @@ We have successfully created caching layers using Memcached, Postgres, and an in
|
|
74
74
|
|
75
75
|
### Better Rails Integration
|
76
76
|
|
77
|
-
When we initially got started with the Contentful ruby models, we encountered one problem that was more frustrating than all others: If a field exists in the content model, but the particular entry we're working with does not have that field populated, then accessing that field raised a `NoMethodError`. This caused us to litter our code with `if defined?(entry.my_field)` which is bad practice.
|
77
|
+
When we initially got started with the Contentful ruby models, we encountered one problem that was more frustrating than all others: If a field exists in the content model, but the particular entry we're working with does not have that field populated, then accessing that field raised a `NoMethodError`. This caused us to litter our code with `if defined?(entry.my_field)` which is bad practice.
|
78
78
|
|
79
79
|
We decided it was better to not rely on `method_missing?` (what contentful.rb does), and instead to use `define_method` in an initializer to generate the methods for our models. This has the advantage that calling `.instance_methods` on a model class includes all the fields present in the content model.
|
80
80
|
|
81
|
+
Note: it appears that [contentful_rb has added an opt-in configuration to return `nil`](https://github.com/contentful/contentful_model#returning-nil-for-fields-which-arent-defined).
|
82
|
+
instead of raising `NoMethodError. We think this should be the default setting,
|
83
|
+
rather than being opt-in.
|
84
|
+
|
81
85
|
We also took advantage of Rails' naming conventions to automatically infer the content type name based on the class name. Thus in our code, we have `app/models/page.rb` which defines `class Page << WCC::Contentful::Model::Page`, and is automatically linked to the `page` content type ID. (Note: this is overridable on a per-model basis)
|
82
86
|
|
83
87
|
All our models are automatically generated at startup which improves response times at the expense of initialization time. In addition, our content model registry allows easy definition of custom models in your `app/models` directory to override fields. This plays nice with other gems like algoliasearch-rails, which allows you to declaratively manage your Algolia indexes. Another example from our flagship watermark.org:
|
@@ -2,36 +2,38 @@
|
|
2
2
|
|
3
3
|
module WCC::Contentful
|
4
4
|
class Engine < ::Rails::Engine
|
5
|
-
initializer 'enable webhook' do
|
6
|
-
config
|
5
|
+
initializer 'enable webhook' do |app|
|
6
|
+
app.config.to_prepare do
|
7
|
+
config = WCC::Contentful.configuration
|
7
8
|
|
8
|
-
|
9
|
-
|
10
|
-
|
9
|
+
jobs = []
|
10
|
+
jobs << WCC::Contentful::SyncEngine::Job if WCC::Contentful::Services.instance.sync_engine&.should_sync?
|
11
|
+
jobs.push(*WCC::Contentful.configuration.webhook_jobs)
|
11
12
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
13
|
+
jobs.each do |job|
|
14
|
+
WCC::Contentful::WebhookController.subscribe(
|
15
|
+
->(event) do
|
16
|
+
begin
|
17
|
+
if job.respond_to?(:perform_later)
|
18
|
+
job.perform_later(event.to_h)
|
19
|
+
else
|
20
|
+
Rails.logger.error "Misconfigured webhook job: #{job} does not respond to " \
|
21
|
+
':perform_later'
|
22
|
+
end
|
23
|
+
rescue StandardError => e
|
24
|
+
warn "Error in job #{job}: #{e}"
|
25
|
+
Rails.logger.error "Error in job #{job}: #{e}"
|
21
26
|
end
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
end,
|
27
|
-
with: :call
|
28
|
-
)
|
29
|
-
end
|
27
|
+
end,
|
28
|
+
with: :call
|
29
|
+
)
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
next unless config&.management_token.present?
|
33
|
+
next unless config.app_url.present?
|
33
34
|
|
34
|
-
|
35
|
+
WebhookEnableJob.set(wait: 10.seconds).perform_later if Rails.env.production?
|
36
|
+
end
|
35
37
|
end
|
36
38
|
|
37
39
|
config.generators do |g|
|
@@ -142,7 +142,7 @@ class WCC::Contentful::RichTextRenderer
|
|
142
142
|
# Check the first row - if it's a header row, render a <thead>
|
143
143
|
first, *rest = node.content
|
144
144
|
if first&.content&.all? { |cell| cell.node_type == 'table-header-cell' }
|
145
|
-
concat(
|
145
|
+
concat(render_table_header(first))
|
146
146
|
else
|
147
147
|
# Otherwise, render it inside the tbody with the rest
|
148
148
|
rest.unshift(first)
|
@@ -152,6 +152,38 @@ class WCC::Contentful::RichTextRenderer
|
|
152
152
|
end
|
153
153
|
end
|
154
154
|
|
155
|
+
def render_table_header(table_row_node)
|
156
|
+
# roll up blank table-header-cells into the previous cell w/ colspan
|
157
|
+
node_contents = []
|
158
|
+
table_row_node.content.each do |node|
|
159
|
+
if node.node_type == 'table-header-cell' &&
|
160
|
+
node_is_blank?(node) &&
|
161
|
+
node_contents.last&.node_type == 'table-header-cell'
|
162
|
+
|
163
|
+
# replace the previous node with a new node with colspan + 1
|
164
|
+
last_node = node_contents.pop
|
165
|
+
node_contents << WCC::Contentful::RichText.tokenize(
|
166
|
+
last_node.as_json.merge(
|
167
|
+
'data' => (last_node['data'] || {}).merge({
|
168
|
+
'colspan' => (last_node['data']&.try('colspan') || 1) + 1
|
169
|
+
})
|
170
|
+
)
|
171
|
+
)
|
172
|
+
|
173
|
+
# And skip adding this blank node
|
174
|
+
next
|
175
|
+
end
|
176
|
+
|
177
|
+
node_contents << node
|
178
|
+
end
|
179
|
+
|
180
|
+
content_tag(:thead) do
|
181
|
+
content_tag(:tr) do
|
182
|
+
render_content(node_contents)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
155
187
|
def render_table_row(node)
|
156
188
|
content_tag(:tr) do
|
157
189
|
render_content(node.content)
|
@@ -160,16 +192,23 @@ class WCC::Contentful::RichTextRenderer
|
|
160
192
|
|
161
193
|
def render_table_cell(node)
|
162
194
|
content_tag(:td) do
|
163
|
-
|
195
|
+
render_table_cell_content(node.content)
|
164
196
|
end
|
165
197
|
end
|
166
198
|
|
167
199
|
def render_table_header_cell(node)
|
168
|
-
content_tag(:th) do
|
169
|
-
|
200
|
+
content_tag(:th, colspan: node.data && node.data['colspan']) do
|
201
|
+
render_table_cell_content(node.content)
|
170
202
|
end
|
171
203
|
end
|
172
204
|
|
205
|
+
def render_table_cell_content(content)
|
206
|
+
# If the content is a single paragraph, render it without the <p> tag
|
207
|
+
return render_content(content.first.content) if content.size == 1 && content.first.node_type == 'paragraph'
|
208
|
+
|
209
|
+
render_content(content)
|
210
|
+
end
|
211
|
+
|
173
212
|
def render_hyperlink(node)
|
174
213
|
content_tag(:a,
|
175
214
|
href: node.data['uri'],
|
@@ -249,6 +288,15 @@ class WCC::Contentful::RichTextRenderer
|
|
249
288
|
|
250
289
|
private
|
251
290
|
|
291
|
+
def node_is_blank?(node)
|
292
|
+
case node.node_type
|
293
|
+
when 'text'
|
294
|
+
node.value.blank?
|
295
|
+
else
|
296
|
+
node.content.all? { |n| node_is_blank?(n) }
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
252
300
|
def resolve_target(target)
|
253
301
|
unless store.present?
|
254
302
|
raise NotConnectedError,
|
@@ -48,8 +48,8 @@ module WCC::Contentful::Test::Double
|
|
48
48
|
},
|
49
49
|
id: SecureRandom.urlsafe_base64,
|
50
50
|
type: 'Asset',
|
51
|
-
createdAt: Time.now.
|
52
|
-
updatedAt: Time.now.
|
51
|
+
createdAt: Time.now.to_formatted_s(:iso8601),
|
52
|
+
updatedAt: Time.now.to_formatted_s(:iso8601),
|
53
53
|
environment: {
|
54
54
|
sys: {
|
55
55
|
id: 'master',
|
@@ -62,8 +62,8 @@ module WCC::Contentful::Test::Factory
|
|
62
62
|
},
|
63
63
|
id: id || SecureRandom.urlsafe_base64,
|
64
64
|
type: 'Entry',
|
65
|
-
createdAt: Time.now.
|
66
|
-
updatedAt: Time.now.
|
65
|
+
createdAt: Time.now.to_formatted_s(:iso8601),
|
66
|
+
updatedAt: Time.now.to_formatted_s(:iso8601),
|
67
67
|
environment: {
|
68
68
|
sys: {
|
69
69
|
id: 'master',
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wcc-contentful
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Watermark Dev
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-10-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: byebug
|
@@ -499,7 +499,7 @@ homepage: https://github.com/watermarkchurch/wcc-contentful/wcc-contentful
|
|
499
499
|
licenses:
|
500
500
|
- MIT
|
501
501
|
metadata:
|
502
|
-
documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.
|
502
|
+
documentation_uri: https://watermarkchurch.github.io/wcc-contentful/1.6/wcc-contentful
|
503
503
|
rubygems_mfa_required: 'true'
|
504
504
|
post_install_message:
|
505
505
|
rdoc_options: []
|
@@ -516,7 +516,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
516
516
|
- !ruby/object:Gem::Version
|
517
517
|
version: '0'
|
518
518
|
requirements: []
|
519
|
-
rubygems_version: 3.
|
519
|
+
rubygems_version: 3.4.10
|
520
520
|
signing_key:
|
521
521
|
specification_version: 4
|
522
522
|
summary: '[](https://rubygems.org/gems/wcc-contentful)
|
@@ -576,14 +576,16 @@ summary: '[](https://
|
|
576
576
|
models, we encountered one problem that was more frustrating than all others: If
|
577
577
|
a field exists in the content model, but the particular entry we''re working with
|
578
578
|
does not have that field populated, then accessing that field raised a `NoMethodError`. This
|
579
|
-
caused us to litter our code with `if defined?(entry.my_field)` which is bad practice.
|
580
|
-
|
581
|
-
|
582
|
-
|
583
|
-
|
584
|
-
|
585
|
-
|
586
|
-
|
579
|
+
caused us to litter our code with `if defined?(entry.my_field)` which is bad practice. We
|
580
|
+
decided it was better to not rely on `method_missing?` (what contentful.rb does),
|
581
|
+
and instead to use `define_method` in an initializer to generate the methods for
|
582
|
+
our models. This has the advantage that calling `.instance_methods` on a model
|
583
|
+
class includes all the fields present in the content model. Note: it appears that
|
584
|
+
[contentful_rb has added an opt-in configuration to return `nil`](https://github.com/contentful/contentful_model#returning-nil-for-fields-which-arent-defined).
|
585
|
+
instead of raising `NoMethodError. We think this should be the default setting,
|
586
|
+
rather than being opt-in. We also took advantage of Rails'' naming conventions
|
587
|
+
to automatically infer the content type name based on the class name. Thus in our
|
588
|
+
code, we have `app/models/page.rb` which defines `class Page << WCC::Contentful::Model::Page`,
|
587
589
|
and is automatically linked to the `page` content type ID. (Note: this is overridable
|
588
590
|
on a per-model basis) All our models are automatically generated at startup which
|
589
591
|
improves response times at the expense of initialization time. In addition, our
|