webflow_sync 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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.