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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3fd731fc709f8ecfcd4ee730a6bc52e693bdd5f160ba00ad4cb5a50978c8a735
4
- data.tar.gz: 20b9b0b06f31eace48c3ababb1c4cbbbc6d2a8143bc29677957305c4ce4dfe23
3
+ metadata.gz: d67d393afd50ea2c1ab321eea762d18111df439d4058f4cdf2281d43418b9b86
4
+ data.tar.gz: 64b7149e4a25410576287ea71692bccb23878e7c9b12b3b013cdaf08f4d1c79c
5
5
  SHA512:
6
- metadata.gz: 9d2200e5b8bbb1c4a1b52a9163fa06c48d90049cc03715359610ab2e3b62d776635d174636b275188489da2cea857ca5a001426489513b15b2d31de749340b16
7
- data.tar.gz: afb2143f431c139dabfa7139eedb27984f0846e6c377efb2cdea8d61336b1532e97ebba18483ea53ff7826e95b1304afeff99805c5ed750e37b93001cfb9067b
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. (Note: this has since been fixed in contentful.rb v2).
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 = WCC::Contentful.configuration
5
+ initializer 'enable webhook' do |app|
6
+ app.config.to_prepare do
7
+ config = WCC::Contentful.configuration
7
8
 
8
- jobs = []
9
- jobs << WCC::Contentful::SyncEngine::Job if WCC::Contentful::Services.instance.sync_engine&.should_sync?
10
- jobs.push(*WCC::Contentful.configuration.webhook_jobs)
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
- jobs.each do |job|
13
- WCC::Contentful::WebhookController.subscribe(
14
- ->(event) do
15
- begin
16
- if job.respond_to?(:perform_later)
17
- job.perform_later(event.to_h)
18
- else
19
- Rails.logger.error "Misconfigured webhook job: #{job} does not respond to " \
20
- ':perform_later'
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
- rescue StandardError => e
23
- warn "Error in job #{job}: #{e}"
24
- Rails.logger.error "Error in job #{job}: #{e}"
25
- end
26
- end,
27
- with: :call
28
- )
29
- end
27
+ end,
28
+ with: :call
29
+ )
30
+ end
30
31
 
31
- next unless config&.management_token.present?
32
- next unless config.app_url.present?
32
+ next unless config&.management_token.present?
33
+ next unless config.app_url.present?
33
34
 
34
- WebhookEnableJob.set(wait: 10.seconds).perform_later if Rails.env.production?
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(content_tag(:thead) { render_content([first]) })
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
- render_content(node.content)
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
- render_content(node.content)
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.to_s(:iso8601),
52
- updatedAt: Time.now.to_s(:iso8601),
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.to_s(:iso8601),
66
- updatedAt: Time.now.to_s(:iso8601),
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',
@@ -2,6 +2,6 @@
2
2
 
3
3
  module WCC
4
4
  module Contentful
5
- VERSION = '1.5.0'
5
+ VERSION = '1.6.0'
6
6
  end
7
7
  end
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.5.0
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-06-08 00:00:00.000000000 Z
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.5/wcc-contentful
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.3.7
519
+ rubygems_version: 3.4.10
520
520
  signing_key:
521
521
  specification_version: 4
522
522
  summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](https://rubygems.org/gems/wcc-contentful)
@@ -576,14 +576,16 @@ summary: '[![Gem Version](https://badge.fury.io/rb/wcc-contentful.svg)](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. (Note:
580
- this has since been fixed in contentful.rb v2). We decided it was better to not
581
- rely on `method_missing?` (what contentful.rb does), and instead to use `define_method`
582
- in an initializer to generate the methods for our models. This has the advantage
583
- that calling `.instance_methods` on a model class includes all the fields present
584
- in the content model. We also took advantage of Rails'' naming conventions to automatically
585
- infer the content type name based on the class name. Thus in our code, we have
586
- `app/models/page.rb` which defines `class Page << WCC::Contentful::Model::Page`,
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