webflow_sync 0.2.5 → 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: f5541d8efea25526da9e623513853d0b2727c0d473251162cc2db71d729ee3c5
4
- data.tar.gz: 45ffc209e988d291a010618debf173530bdecdb1686caf9a23653214265cd300
3
+ metadata.gz: 3fffb6d06856d3cd1a71f9180fff0753b3cf3396dcfeb1e5ed85d8a01d9ff05e
4
+ data.tar.gz: a18bfeb55b4893dc0f9639d69259760e41d3326cda8096a471fc932534687844
5
5
  SHA512:
6
- metadata.gz: e850f8be00f87fe2ebd9ede70cf0adf9d7cceeb0d02cf4b8afafbdb17472915717017e6d8a632562c80dc5acc460cb0cbcb3c655b08c5046cef323800abe7779
7
- data.tar.gz: 606363c28363aeaf7cd8f3a27859db3a8d5c0db929af486fc0456b27e5ba1ff917d56180e5152a959c337fdc787b016a20335c11dd4ab3ad64c9fec86ef2f800
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,9 +8,9 @@ module WebflowSync
8
8
  included do
9
9
  attr_accessor :skip_webflow_sync
10
10
 
11
- after_create :create_webflow_item
12
- after_update :update_webflow_item
13
- after_destroy :destroy_webflow_item
11
+ after_commit :create_webflow_item, on: :create
12
+ after_commit :update_webflow_item, on: :update
13
+ after_commit :destroy_webflow_item, on: :destroy
14
14
 
15
15
  def create_webflow_item
16
16
  return if self.skip_webflow_sync || WebflowSync.configuration.skip_webflow_sync
@@ -8,15 +8,41 @@ module WebflowSync
8
8
  @site_id = site_id
9
9
  end
10
10
 
11
- def create_item(record, collection_slug) # rubocop:disable Metrics/MethodLength
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
+
34
+ def get_item(collection_slug, webflow_item_id)
12
35
  collection = find_webflow_collection(collection_slug)
13
- response = client.create_item(
14
- collection['_id'],
15
- record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true
16
- )
17
36
 
18
- # use update_column to skip callbacks to prevent WebflowSync::ItemSync to kick off
19
- if record.update_column(:webflow_item_id, response['_id']) # rubocop:disable Rails/SkipsModelValidations
37
+ make_request(:item, collection['_id'], webflow_item_id)
38
+ end
39
+
40
+ def create_item(record, collection_slug)
41
+ collection = find_webflow_collection(collection_slug)
42
+ response = make_request(:create_item, collection['_id'],
43
+ record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true)
44
+
45
+ if update_record_colums(record, response)
20
46
  puts "Created #{record.inspect} in #{collection_slug}"
21
47
  response
22
48
  else
@@ -27,21 +53,31 @@ module WebflowSync
27
53
 
28
54
  def update_item(record, collection_slug)
29
55
  collection = find_webflow_collection(collection_slug)
30
- response = client.update_item(
31
- { '_cid' => collection['_id'], '_id' => record.webflow_item_id },
32
- record.as_webflow_json.reverse_merge(_archived: false, _draft: false), live: true
33
- )
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
+
34
59
  puts "Updated #{record.inspect} in #{collection_slug}"
35
60
  response
36
61
  end
37
62
 
38
63
  def delete_item(collection_slug, webflow_item_id)
39
64
  collection = find_webflow_collection(collection_slug)
40
- 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
+
41
70
  puts "Deleted #{webflow_item_id} from #{collection_slug}"
42
71
  response
43
72
  end
44
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
+
45
81
  private
46
82
 
47
83
  def client
@@ -52,11 +88,50 @@ module WebflowSync
52
88
  @collections ||= client.collections(site_id)
53
89
  end
54
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
+
55
107
  def find_webflow_collection(collection_slug)
56
108
  response = collections.find { |collection| collection['slug'] == collection_slug }
57
109
  raise "Cannot find collection #{collection_slug} for Webflow site #{site_id}" unless response
58
110
 
59
111
  response
60
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
61
136
  end
62
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 = '0.2.5'
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: 0.2.5
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-02-22 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.3
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.