webflow_sync 1.1.0 → 2.0.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: 5e85c49b258ebbde8c6d5984893be9f59acf389505f0af30951d98fccc4b2f0d
4
- data.tar.gz: '09b216274b17cfd61ff9aa1c2a2cc984b12655302daa4d25e3bb0e37a29b1180'
3
+ metadata.gz: 3fffb6d06856d3cd1a71f9180fff0753b3cf3396dcfeb1e5ed85d8a01d9ff05e
4
+ data.tar.gz: a18bfeb55b4893dc0f9639d69259760e41d3326cda8096a471fc932534687844
5
5
  SHA512:
6
- metadata.gz: 3bea1e564a550a72cf7164e3cce4fb7710478e3683c8a1067b1dfc790b87679a59f4a03985fdf610628deeb4334d0d5bd540391afb85d4a41cbb85b67f323525
7
- data.tar.gz: bc6bba426b31b48d20caa8ebbfa88e3ec3237b51faa8ac520e715c73fdedf18c1807eff59932e512200d47ed0fb7e921c0ca10b2cd5531cba5cc0096487f6323
6
+ metadata.gz: d60c06119a661385dabfff3017fdfe72f3c515b0ba13c208486bff38b2cddc14f40bf5557fe691e5e66215d0f9fe75c7de0a8964e4ca6be725ef61fc3157e626
7
+ data.tar.gz: 981e3169932af0aa8b7a528738d04da9e9a63cb0021c8c2bd6e3386e924384ee7cc3ae4f4840a02a4df95864d2b330755f83eea287d1752547d0124a1c7d192e
data/README.md CHANGED
@@ -36,6 +36,34 @@ Run API token Rails generator and follow instructions:
36
36
  ```bash
37
37
  bundle exec rails generate webflow_sync:api_token_flow
38
38
  ```
39
+ ### Configuration options
40
+
41
+ In `config/initializers/webflow_sync.rb` you can specify configuration options:
42
+
43
+ 1. `api_token`
44
+ 2. `webflow_site_id`
45
+ 3. `skip_webflow_sync` - skip synchronization for different environments
46
+ 4. `sync_webflow_slug` - save slug generated on WebFlow to the Rails database, in the Rails model column.
47
+
48
+ This can be useful if you want to link to WebFlow item directly from your Rails app:
49
+
50
+ ```rb
51
+ link_to('View on site', "https://#{webflow_domain}/articles/#{record.webflow_slug}", target: :blank)
52
+ ```
53
+
54
+ To save slug generated on WebFlow in Rails model, `webflow_slug` column:
55
+
56
+ 1. add `webflow_slug` column on the model table, then
57
+ 2. set the `sync_webflow_slug` option to `true`.
58
+
59
+ Example:
60
+
61
+ ```rb
62
+ WebflowSync.configure do |config|
63
+ config.skip_webflow_sync = ActiveModel::Type::Boolean.new.cast(ENV.fetch('SKIP_WEBFLOW_SYNC'))
64
+ config.sync_webflow_slug = ActiveModel::Type::Boolean.new.cast(ENV.fetch('SYNC_WEBFLOW_SLUG'))
65
+ end
66
+ ```
39
67
 
40
68
  ### Add WebflowSync to models
41
69
 
@@ -8,20 +8,41 @@ module WebflowSync
8
8
  @site_id = site_id
9
9
  end
10
10
 
11
+ def get_all_items(collection_slug:, page_limit: 100) # rubocop:disable Metrics/MethodLength
12
+ collection_id = find_webflow_collection(collection_slug)['_id']
13
+ max_items_per_page = page_limit # Webflow::Error: 'limit' must be less than or equal to 100
14
+ first_page_number = 1
15
+
16
+ result = make_request(:paginate_items, collection_id, page: first_page_number, per_page: max_items_per_page)
17
+ puts "Get all items from WebFlow for #{collection_slug} page: #{first_page_number}"
18
+
19
+ total_items = result['total']
20
+ total_pages = (total_items.to_f / max_items_per_page).ceil
21
+ items = result['items']
22
+
23
+ (2..total_pages).each do |page_number|
24
+ next_page_items = make_request(:paginate_items, collection_id,
25
+ page: page_number, per_page: max_items_per_page)['items']
26
+ puts "Get all items from WebFlow for #{collection_slug} page: #{page_number}"
27
+
28
+ items.concat next_page_items
29
+ end
30
+
31
+ items
32
+ end
33
+
11
34
  def get_item(collection_slug, webflow_item_id)
12
35
  collection = find_webflow_collection(collection_slug)
13
- client.item(collection['_id'], webflow_item_id)
36
+
37
+ make_request(:item, collection['_id'], webflow_item_id)
14
38
  end
15
39
 
16
- def create_item(record, collection_slug) # rubocop:disable Metrics/MethodLength
40
+ def create_item(record, collection_slug)
17
41
  collection = find_webflow_collection(collection_slug)
18
- response = client.create_item(
19
- collection['_id'],
20
- record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true
21
- )
42
+ response = make_request(:create_item, collection['_id'],
43
+ record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true)
22
44
 
23
- # use update_column to skip callbacks to prevent WebflowSync::ItemSync to kick off
24
- if record.update_column(:webflow_item_id, response['_id']) # rubocop:disable Rails/SkipsModelValidations
45
+ if update_record_colums(record, response)
25
46
  puts "Created #{record.inspect} in #{collection_slug}"
26
47
  response
27
48
  else
@@ -32,21 +53,31 @@ module WebflowSync
32
53
 
33
54
  def update_item(record, collection_slug)
34
55
  collection = find_webflow_collection(collection_slug)
35
- response = client.update_item(
36
- { '_cid' => collection['_id'], '_id' => record.webflow_item_id },
37
- record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true
38
- )
56
+ response = make_request(:update_item, { '_cid' => collection['_id'], '_id' => record.webflow_item_id },
57
+ record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true)
58
+
39
59
  puts "Updated #{record.inspect} in #{collection_slug}"
40
60
  response
41
61
  end
42
62
 
43
63
  def delete_item(collection_slug, webflow_item_id)
44
64
  collection = find_webflow_collection(collection_slug)
45
- response = client.delete_item({ '_cid' => collection['_id'], '_id' => webflow_item_id })
65
+ response = make_request(:delete_item, { '_cid' => collection['_id'], '_id' => webflow_item_id })
66
+ # When the item is removed from WebFlow, it's still visible throughout the WebFlow site (probably due to some caching).
67
+ # To remove the item immediately from the WebFlow site, we need to publish the site.
68
+ publish
69
+
46
70
  puts "Deleted #{webflow_item_id} from #{collection_slug}"
47
71
  response
48
72
  end
49
73
 
74
+ def publish
75
+ response = make_request(:publish, site_id, domain_names: domain_names)
76
+
77
+ puts "Publish all domains for Webflow site with id: #{site_id}"
78
+ response
79
+ end
80
+
50
81
  private
51
82
 
52
83
  def client
@@ -57,11 +88,50 @@ module WebflowSync
57
88
  @collections ||= client.collections(site_id)
58
89
  end
59
90
 
91
+ def domain_names
92
+ @domain_names ||= find_domain_names
93
+ end
94
+
95
+ def find_domain_names
96
+ # client.domains request does not return the default domain
97
+ # We need to get default domain name if there are no custom domains set to avoid error:
98
+ # Webflow::Error: Domain not found for site
99
+ site = client.site(site_id)
100
+ default_domain_name = "#{site['shortName']}.webflow.io"
101
+ names = [default_domain_name]
102
+ client.domains(site_id).each { |domain| names << domain['name'] }
103
+
104
+ names
105
+ end
106
+
60
107
  def find_webflow_collection(collection_slug)
61
108
  response = collections.find { |collection| collection['slug'] == collection_slug }
62
109
  raise "Cannot find collection #{collection_slug} for Webflow site #{site_id}" unless response
63
110
 
64
111
  response
65
112
  end
113
+
114
+ def update_record_colums(record, response)
115
+ # use update_column to skip callbacks to prevent WebflowSync::ItemSync to kick off
116
+ if WebflowSync.configuration.sync_webflow_slug
117
+ record.update_columns(webflow_item_id: response['_id'], webflow_slug: response['slug']) # rubocop:disable Rails/SkipsModelValidations
118
+ else
119
+ record.update_column(:webflow_item_id, response['_id']) # rubocop:disable Rails/SkipsModelValidations
120
+ end
121
+ end
122
+
123
+ def make_request(method_name, *args, retries: 0, **kwargs)
124
+ if kwargs.present?
125
+ client.public_send(method_name, *args, **kwargs)
126
+ else
127
+ client.public_send(method_name, *args)
128
+ end
129
+ rescue Webflow::Error => e
130
+ raise if retries >= 8 || e.message.strip != 'Rate limit hit'
131
+
132
+ puts "Sleeping #{2**retries} seconds"
133
+ sleep 2**retries
134
+ make_request(method_name, *args, retries: retries + 1, **kwargs)
135
+ end
66
136
  end
67
137
  end
@@ -4,4 +4,5 @@ WebflowSync.configure do |config|
4
4
  # config.api_token = ENV.fetch('WEBFLOW_API_TOKEN')
5
5
  # config.skip_webflow_sync = Rails.env.test? # default
6
6
  config.webflow_site_id = ENV.fetch('WEBFLOW_SITE_ID')
7
+ config.sync_webflow_slug = ENV.fetch('SYNC_WEBFLOW_SLUG')
7
8
  end
@@ -18,7 +18,7 @@ module WebflowSync
18
18
  end
19
19
 
20
20
  class Configuration
21
- attr_accessor :skip_webflow_sync, :webflow_site_id
21
+ attr_accessor :skip_webflow_sync, :webflow_site_id, :sync_webflow_slug
22
22
  attr_reader :api_token
23
23
 
24
24
  def api_token=(value)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module WebflowSync
4
- VERSION = '1.1.0'
4
+ VERSION = '2.0.0'
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: webflow_sync
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Viktor
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-25 00:00:00.000000000 Z
11
+ date: 2021-06-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -173,7 +173,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
173
173
  - !ruby/object:Gem::Version
174
174
  version: '0'
175
175
  requirements: []
176
- rubygems_version: 3.2.11
176
+ rubygems_version: 3.0.9
177
177
  signing_key:
178
178
  specification_version: 4
179
179
  summary: Keep Rails models in sync with WebFlow.